sql >> Databáze >  >> RDS >> Mysql

Je lepší filtrovat sadu výsledků pomocí klauzule WHERE nebo pomocí kódu aplikace?

Základním pravidlem pro jakoukoli aplikaci je nechat DB dělat věci, které dělá dobře:filtrování, řazení a spojování.

Rozdělte dotazy na jejich vlastní funkce nebo metody třídy:

$men = $foo->fetchMaleUsers();
$women = $foo->fetchFemaleUsers();

Aktualizovat

Vzal jsem Stevenovu ukázku PostgreSQL dotazu na skenování celé tabulky, který byl dvakrát lepší než dva samostatné indexované dotazy, a napodobil jsem to pomocí MySQL (které je použito ve skutečné otázce):

Schéma

CREATE TABLE `gender_test` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `gender` enum('male','female') NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26017396 DEFAULT CHARSET=utf8

Změnil jsem typ pohlaví tak, aby nebyl VARCHAR(20), protože je to pro účely tohoto sloupce realističtější, místo libovolné hodnoty DOUBLE také uvádím primární klíč, jak byste očekávali v tabulce.

Neindexované výsledky

mysql> select sql_no_cache * from gender_test WHERE gender = 'male';

12995993 rows in set (31.72 sec)

mysql> select sql_no_cache * from gender_test WHERE gender = 'female';

13004007 rows in set (31.52 sec)

mysql> select sql_no_cache * from gender_test;

26000000 rows in set (32.95 sec)

Věřím, že to nepotřebuje vysvětlení.

Indexované výsledky

ALTER TABLE gender_test ADD INDEX (gender);

...

mysql> select sql_no_cache * from gender_test WHERE gender = 'male';

12995993 rows in set (15.97 sec)

mysql> select sql_no_cache * from gender_test WHERE gender = 'female';

13004007 rows in set (15.65 sec)

mysql> select sql_no_cache * from gender_test;

26000000 rows in set (27.80 sec)

Zde zobrazené výsledky jsou radikálně odlišné od Stevenových údajů. Indexované dotazy fungují téměř dvakrát rychlejší než skenování celé tabulky. Toto je ze správně indexované tabulky pomocí definic sloupců zdravého rozumu. PostgreSQL vůbec neznám, ale ve Stevenově příkladu musí být nějaká podstatná chybná konfigurace, aby se neukázaly podobné výsledky.

Vzhledem k pověsti PostgreSQL, že dělá věci lépe než MySQL, nebo alespoň tak dobře, si troufám tvrdit, že PostgreSql by prokázal podobný výkon, pokud by byl správně používán.

Všimněte si také, že na stejném počítači příliš zjednodušená smyčka for pro provedení 52 milionů porovnání trvá dalších 7,3 sekund provést.

<?php
$N = 52000000;
for($i = 0; $i < $N; $i++) {
    if (true == true) {
    }
}

Myslím, že je celkem zřejmé, jaký je lepší přístup vzhledem k těmto údajům.



  1. sql:DELETE + INSERT vs UPDATE + INSERT

  2. Příklady MINUTE() – MySQL

  3. Jak otestovat uloženou proceduru Oracle s návratovým typem RefCursor?

  4. MySQL C++ Connector nevyřešený externí symbol _get_driver_instance