it-swarm-eu.dev

Ovlivňuje pořadí sloupců v klauzuli WHERE v MySQL výkon dotazu?

Mám problémy s výkonem u určitých databázových dotazů, které mají velké možné sady výsledků.

Dotčený dotaz, mám tři ANDs v klauzuli WHERE

Záleží na pořadí ustanovení?

Stejně jako v případě, kdybych vložil první klauzuli ASI_EVENT_TIME (protože by tím byla odstraněna většina výsledků z kterékoli z klauzulí.

Zlepší se tím doba běhu dotazu?

DOTAZ:

SELECT DISTINCT  activity_seismo_info.* 
FROM `activity_seismo_info` 
WHERE 
    activity_seismo_info.ASI_ACTIVITY_ID IS NOT NULL  AND 
    activity_seismo_info.ASI_SEISMO_ID IN (43,44,...,259) AND 
    (
        activity_seismo_info.ASI_EVENT_TIME>='2011-03-10 00:00:00' AND 
        activity_seismo_info.ASI_EVENT_TIME<='2011-03-17 23:59:59'
    ) 

ORDER BY activity_seismo_info.ASI_EVENT_TIME DESC

VYSVĚTLENÍ dotazu:

+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+ 
| id | select_type | table   | type  | possible_keys             | key          | key_len | ref  | rows  | Extra                       |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+ 
|  1 | SIMPLE      | act...o | range | act...o_FI_1,act...o_FI_2 | act...o_FI_1 | 5       | NULL | 65412 | Using where; Using filesort |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+

Použitím:

PHP 5.2

MySQL 5.0.51a-3ubuntu5.4

Propel 1.3

Symfonie 1.2.5

41
Patrick

Nemyslím si. Optimalizátor dotazů by měl být dostatečně chytrý.

Můžete zkusit přeuspořádat klauzule WHERE a zjistit, že EXPLAINS vám v každém případě říká to samé.


Co lze udělat pro optimalizaci tohoto dotazu: Existuje index ASI_EVENT_TIME? (Toto je pro tento dotaz nejdůležitější, protože také třídíte výsledky pomocí tohoto dotazu).

Existují indexy v dalších dvou polích (ASI_SEISMO_ID a ASI_ACTIVITY_ID)?

Bylo by užitečné, kdybyste zveřejnili strukturu tabulky.

26
ypercubeᵀᴹ

Od dokumentace :

Pokud tabulka obsahuje index více sloupců, může optimalizátor použít k nalezení řádků libovolnou předponu indexu vlevo. Například pokud máte index ve třech sloupcích na (col1, col2, col3), máte možnosti indexovaného vyhledávání na (col1), (col1, col2) a (col1, col2, col3).

MySQL nemůže použít index, pokud sloupce netvoří předponu indexu zcela vlevo.

Takže ano, mělo by to být stejné jako pořadí sloupců v složený index .

15
Gaius

Ne, na tom nezáleží.

Optimalizátor provede spoustu jednoduchých transformací hned poté, co analyzuje SQL - to je jedna z nich.

10
Morgan Tocker

KDE foo a bar

optimalizuje to samé jako

KDE bar a foo

Nicméně,

KDE nerovnoměrný # 1 a nerovný # 2

Nelze optimalizovat obě části. Například,

KDE MEZI 1 a 3 A b> 17

nemůže dobře využít INDEX (a, b) nebo INDEX (b, a)

Abychom to řekli jinak, nejprve se použijí všechny '=' testy A společně v klauzuli WHERE, potom jeden non - '=' (IN, MEZI,> atd.) Lze manipulovat. Nelze efektivně optimalizovat více než jeden.

Váš dotaz obsahuje 3 takové doložky.

Jak se ukazuje, INDEX (EVENT_TIME) je pravděpodobně nejužitečnější - pomůže s jedním z AND a mohl by být použit k tomu, aby se předešlo "fileort" pro ORDER BY.

Pokud neexistují duplicitní řádky (proč by to sakra mělo být?), Zbavte se DISTINCT. To způsobuje ještě větší úsilí.

Při kladení dotazů na výkon uveďte prosím SHOW CREATE TABLE a SHOW TABLE STATUS.

Aktualizovat ... Novější verze (např. MySQL 5.7) mohou v některých situacích zacházet s IN( list of constants ) téměř jako =. Chcete-li hrát bezpečně, držte se této objednávky (každá část je volitelná):

  1. Jakékoli číslo =.
  2. Někteří INs.
  3. Nejvýše jeden rozsah.
8
Rick James

MySQL, kde optimalizační dokument říká:

Můžete být v pokušení přepsat své dotazy, aby se aritmetické operace zrychlily a přitom obětovaly čitelnost. Protože MySQL provádí podobné optimalizace automaticky , můžete se této práci často vyhnout a dotaz nechat ve srozumitelnější a udržovatelnější podobě. Následují některé optimalizace, které MySQL provádí:

  • ...

  • Pro každou tabulku v spojení se vytvoří jednodušší WHERE , aby se získalo rychlé WHERE vyhodnocení tabulky a také přeskočit řádky co nejdříve .

  • Každý index tabulky je dotazován a použije se nejlepší index, pokud optimalizátor věří, že je efektivnější použití skenování tabulky . Najednou bylo použito skenování na základě toho, zda nejlepší index překročil více než 30% tabulky, ale pevné procento již neurčuje výběr mezi použitím indexu nebo skenování. Optimalizátor je nyní složitější a svůj odhad zakládá na dalších faktorech, jako je velikost tabulky, počet řádků a velikost bloku I/O.

Je proto racionální, aby optimalizátor dotazů vynechal HOW-order, abychom použili sloupce v dotazu (nejen MySQL, ale SQL je deklarativní jazyk a musíme dělat to, co chceme, ne, jak chceme.

I přesto ráda mám stejné řazení pro sloupce složeného klíče v dotazu, ale někdy je to nevyhnutelné, například když používáme ORM nebo ActiveRecord, v některých rámcích, jako je yii2, přizpůsobení kritérií vztahu bude připojeno na konec "on", ale stále potřebujeme schopnosti QueryBuilders v různých částech aplikace.

1
Alix