Dlaczego STRAIGHT JOIN tak drastycznie poprawia to zapytanie i co to oznacza, gdy jest napisane po słowie kluczowym SELECT?

Mam następujące zapytanie MySql:

select t1.*
from Table1 t1
inner join Table2 t2
on t1.CommonID = t2.CommonID
where t1.FilterID = 1

Uruchomienie zajmuje około 30 sekund, co było dziwne, ponieważ jeśli skomentuję join lub klauzulę where, zajmuje mniej niż sekundę: tj.

select t1.*
from Table1 t1
where t1.FilterID = 1

Lub

select t1.*
from Table1 t1
inner join Table2 t2
on t1.CommonID = t2.CommonID
Każdy zajmuje mniej niż sekundę.

Następnie jest słowo kluczowe STRAIGHT_JOIN, które mogę znaleźć jedno odniesienie, tutaj: http://dev.mysql.com/doc/refman/5.0/en/join.html

STRAIGHT_JOIN jest podobny do JOIN, z tym, że lewy stół jest zawsze Przeczytaj przed prawym stołem. To może być stosowane w tych (kilku) przypadkach dla który optymalizator łączenia stawia stoliki w złej kolejności.

Co? Mogę napisać:
select t1.*
from Table1 t1
STRAIGHT_JOIN  Table2 t2
on t1.CommonID = t2.CommonID
where t1.FilterID = 1

I zapytanie zostanie wykonane w mniej niż sekundę.

Jeszcze dziwniejsze, mogę napisać:

select STRAIGHT_JOIN  t1.*
from Table1 t1
inner join Table2 t2
on t1.CommonID = t2.CommonID
where t1.FilterID = 1

I zajmuje to mniej niż sekundę, a ta składnia nie wydaje się nawet legalna.

Domyślam się, że drugi przykład oznacza, że STRAIGHT_JOIN będzie używany, gdy INNER JOIN jest napisane, ale nie mogę znaleźć żadnej dokumentacji na ten temat.

Co tu się dzieje i w jaki sposób "join optimizer" może skutkować tak stosunkowo niską wydajnością? Czy zawsze powinienem używać STRAIGHT_JOIN? Skąd mam wiedzieć, kiedy go używać?

Table1 i Table2 mają klucze podstawowe typu integer; FilterID jest kluczem obcym do innej tabeli; kolumny CommonID są kluczami obcymi do trzeciej tabeli. Obaj mają na sobie indeksy. Silnik bazy danych jest InnoDB.

Dzięki

 49
Author: zod, 2011-04-28

1 answers

Co tu się dzieje i w jaki sposób "join optimizer" może skutkować tak stosunkowo niską wydajnością?

STRAIGHT_JOIN wymusza kolejność łączenia tabel, więc {[1] } jest skanowany w pętli zewnętrznej i table2 W pętli wewnętrznej.

Optymalizator nie jest doskonały (choć całkiem przyzwoity), a najbardziej prawdopodobną przyczyną są nieaktualne statystyki.

Czy zawsze używam STRAIGHT_JOIN

Nie, tylko wtedy, gdy optymalizator się myli. Może tak być, jeśli Twoje dane dystrybucja jest mocno przekrzywiona lub nie może być poprawnie obliczona (np. dla indeksów przestrzennych lub pełnotekstowych).

Skąd mogę wiedzieć, kiedy go użyć, czy nie?

Powinieneś zbierać statystyki, budować plany na oba sposoby i zrozumieć, co oznaczają te plany.

Jeśli widzisz, że:

  1. Automatycznie generowany plan nie jest optymalny i nie można go poprawić standardowymi sposobami,

  2. Wersja STRAIGHT_JOIN jest lepsza, rozumiesz to zawsze będzie i zrozumie dlaczego zawsze będzie

, Następnie użyj STRAIGHT_JOIN.

 40
Author: Quassnoi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-28 12:59:37