2009-11-08 10 views
7

zauważyłem coś dziwnego podczas wykonywania select z 2 tabele:MySQL Query Wybierz za pomocą sub-select trwa zbyt długo

SELECT * FROM table_1 WHERE id IN (
    SELECT id_element FROM table_2 WHERE column_2=3103); 

To zapytanie wziął approximatively 242 sekund.

Ale kiedy wykonał podkwerenda

SELECT id_element FROM table_2 WHERE column_2=3103 

zajęło mniej niż 0.002s (i wynikał 2 rzędy).
Wtedy, kiedy nie

SELECT * FROM table_1 WHERE id IN (/* prev.result */) 

było tak samo: 0.002s.

Zastanawiam się, dlaczego MySQL wykonuje pierwsze zapytanie, biorąc pod uwagę znacznie więcej czasu niż dwa ostatnie zapytania oddzielnie? Czy jest to optymalne rozwiązanie do wybierania czegoś na podstawie wyników pod-zapytania?

Pozostałe szczegóły: table_1 ma około. 9000 wierszy i table_2 ma 90000 wierszy.

Po dodaniu indeksu na column_2 z table_2 pierwsze zapytanie zajęło 0,15 s.

+0

ile wyników daje wybór wewnątrz? – Dani

+0

Czy mógłbyś opublikować wynik uruchomienia 'WYBIERZ WYBIERZ * Z tabeli_1 WHERE id IN (SELECT id_element FROM table_2 WHERE column_2 = 3103)'. Spowoduje to wyświetlenie, jakiego planu zapytań i indeksów używa MySQL. –

+0

@Dani post stwierdza, że ​​zapytanie wewnętrzne zwraca 2 wiersze. –

Odpowiedz

7

Być może analizator zapytań ocenia podzapytanie dla każdego wiersza.

Spróbuj wymienić podkwerenda ze związkiem INNER JOIN, i sprawdzić, czy to poprawia wydajność:

SELECT  * 
FROM  table_1 t1 
INNER JOIN table_2 t2 
ON   t1.id = t2.id_element 
      AND t2.column_2 = 3103 
+0

Działa to poprawnie; ~ 0.2s –

2

To jest znany błąd w mysql przed ver 6.

obejść znalazłem to:

SELECT * Z table_1 GDZIE ID w ( SELECT id_element OD (SELECT id_element Z table_2 GDZIE column_2 = 3103), a q)

+1

Czy możesz dodać link do szczegółów błędu? – aviv

+0

To obejście ogoliło trochę czasu wolnego w mojej konkretnej kwerendzie (od 50 sekund do 10 sekund, ale dwa oddzielne zapytania wciąż wygrywają w połączeniu .7sec – scum

0

Mam ten sam problem. Dodałem INDEX do tabel (domyślam się, że już masz) i użyłeś dyrektywy USE INDEX. W twoim przypadku powinno to wyglądać tak:

SELECT * FROM table_1 USE INDEX(id) 
WHERE id IN (SELECT id_element FROM table_2 WHERE column_2=3103); 

Dla mnie to polepszyło.

+0

Czy to nie jest autoinrecja twojego pola 'id'? MySQL powinien wiedzieć, aby go używać bez określania to. –