Pytanie Czy podzapytania są buforowane przez MySQL, gdy są używane w klauzuli WHERE?


W następującym zapytaniu:

SELECT column_a, column_b FROM table_a WHERE
    column_b IN (SELECT b_id FROM table_b)

Czy podzapytanie SELECT b_id FROM table_b buforowany przez analizator składni SQL, czy szybciej byłoby wykonać zapytanie wcześniej, zapisać jako zmienną (na przykład w PHP), a następnie przekazać te wartości jako ciąg znaków CSV?

na przykład

SELECT column_a, column_b FROM table_a WHERE
    column_b IN (1,3,4,6,8,10,16,18)

12
2017-08-08 15:58


pochodzenie


Za pomocą IN z podzapytaniem to okropny pomysł. Lepiej, aby uzyskać wyniki, które chcesz tutaj z join, ponieważ zapytanie jest zasadniczo equi-join. SELECT column_a, column_b FROM table_a JOIN table_b ON column_b = b_id - Tim Seguine
@TimSeguine: Dlaczego to okropny pomysł? Gdyby table_b jest tabelą relacji N: M, z której jeden otrzyma wiele wierszy table_a Jeśli JOIN Jest używane. To może być niepożądane. - naitsirch
@naitsirch To zły pomysł, ponieważ MySQL ma złe wsparcie dla zależnych podzapytań. Jeśli możesz w jakikolwiek sposób ich uniknąć, prawdopodobnie powinieneś. Dobrze wybrane GROUP BY w większości przypadków eliminuje zbędne wyniki. - Tim Seguine
Nie jesteśmy zależni (myślę, że miałeś na myśli współzależny) podzapytanie w pytaniu (zob tutaj dla wyjaśnienia skorelowanych podzapytań). O ile widzę, to zapytanie powinno być tak wydajne jak JOIN, ponieważ musi być wykonane tylko raz. - naitsirch
@naitsirch masz rację, to nie jest skorelowane. Mimo to, stare wersje MySQL zostały zoptymalizowane IN podzapytania czasami bardzo źle (oceniając całe podzapytanie dla każdego wiersza tabeli zewnętrznej, w tym przypadku). A kiedy mówię stary, mam na myśli do 5,5. Przepisywanie za pomocą JOIN, kiedy było to możliwe, był zwykle bardzo dobrym pomysłem. - ypercubeᵀᴹ


Odpowiedzi:


Spójrz na użycie EXPLAIN EXTENDED aby w pełni zilustrować efekty zastosowane w podzapytaniu.

Na przykład:

EXPLAIN EXTENDED
SELECT column_a, column_b FROM table_a WHERE
    column_b IN (SELECT b_id FROM table_b)

Jeśli nie przyniosą pożądanych rezultatów buforowania, być może zainteresuje Cię ich przechowywanie w pamięci (memcache, redis), w pliku (przy użyciu Biblioteki plików PHP) lub w osobnej pamięci podręcznej SQL.


6
2017-08-08 16:00



To jest najbardziej niepoprawna odpowiedź, jaką widziałem dzisiaj. - ypercubeᵀᴹ
@ ypercubeᵀᴹ i każdemu, kto go przegłosował, czy możesz wyjaśnić lub podać alternatywne odpowiedzi? - Secret