Bartosz Ratajczyk

Bartosz Ratajczyk MS SQL Developer

Temat: [MySQL] Jak inaczej napisać LEFT JOINa z warunkiem IS NULL

Zadanie: wybrać z tabeli klienci pięciu klientów, którzy nie znajdują się w tabeli wyniki

Niech:
klienci (nr_tel, reszta_danych) ~ 1.5 mln rekordów
wyniki (nr_tel, status, reszta_danych) ~60 tys rekordów

Standardowo:

SELECT
klienci.nr_tel
FROM klienci
LEFT JOIN wyniki ON klienci.nr_tel = wyniki.nr_tel
WHERE
wyniki.status IS NULL
LIMIT 5;

Ale strasznie się to ślimaczy, bo z tego co pokazuje EXPLAIN SELECT nie są wykorzystywane w tym zapytaniu indeksy na kolumnach nr_tel (jeśli warunek jest w stylu wyniki.status = 1 to indeksy są wykorzystywane). Czy da się to jakoś zgrabnie przepisać, żeby to przyspieszyło?
Daniel Jurak

Daniel Jurak analityk
programista,
architekt danych PKO
BP SA

Temat: [MySQL] Jak inaczej napisać LEFT JOINa z warunkiem IS NULL

a jakos tak:

SELECT
klienci.nr_tel
FROM klienci
WHERE EXISTS (SELECT 1 FROM wyniki WHERE klienci.nr_tel = wyniki.nr_tel)
LIMIT 5

albo i to wydaje mi sie najszybsze:

SELECT
klienci.nr_tel
FROM
(SELECT
wyniki.nr_tel
FROM
WYNIKI LIMIT 5) as DT1
LEFT JOIN klienci
on klienci.nr_tel = DT1.nr_tel

konto usunięte

Temat: [MySQL] Jak inaczej napisać LEFT JOINa z warunkiem IS NULL

ciach... ;)Rafał Wardas edytował(a) ten post dnia 28.09.09 o godzinie 16:22
Filip Achramowicz

Filip Achramowicz Telecom VAS &
fotoach.pl

Temat: [MySQL] Jak inaczej napisać LEFT JOINa z warunkiem IS NULL

pierwszy schemat Daniela wydaje się 2 razy szybszy od pierwotnegoFilip Achramowicz edytował(a) ten post dnia 28.09.09 o godzinie 16:16
Paweł Ryszawa

Paweł Ryszawa Senior Technical
Leader, EY GDS

Temat: [MySQL] Jak inaczej napisać LEFT JOINa z warunkiem IS NULL

Ale chyba Daniel pokazał selekta na coś dokładnie odwrotnego - na tych klientów, którzy MAJĄ wpisy w wynikach (a miało pokazać tych co NIE MAJĄ). Zatem, jeśli już, to w pierszym selekcie WHERE NOT EXISTS a nie WHERE EXISTS. A drugiego nie ma co poprawiać...
Daniel Jurak

Daniel Jurak analityk
programista,
architekt danych PKO
BP SA

Temat: [MySQL] Jak inaczej napisać LEFT JOINa z warunkiem IS NULL

Paweł Ryszawa:
Ale chyba Daniel pokazał selekta na coś dokładnie odwrotnego - na tych klientów, którzy MAJĄ wpisy w wynikach (a miało pokazać tych co NIE MAJĄ). Zatem, jeśli już, to w pierszym selekcie WHERE NOT EXISTS a nie WHERE EXISTS. A drugiego nie ma co poprawiać...

faktycznie, niedokladnie doczytalem :)
WHERE NOT EXISTS jak najbardziej.
Bartosz Ratajczyk

Bartosz Ratajczyk MS SQL Developer

Temat: [MySQL] Jak inaczej napisać LEFT JOINa z warunkiem IS NULL

Dzięki. NOT EXISTS wcześniej nie testowałem (badałem np. NOT IN) i wydaje się, że działa o wiele szybciej. Wydaje się, bo przeprowadziłem za mało testów, ale teraz poszło przynajmniej trzy razy szybciej niż LEFT JOIN.
Maciej Filipiak

Maciej Filipiak właściciel, VizMedia

Temat: [MySQL] Jak inaczej napisać LEFT JOINa z warunkiem IS NULL

Jezeli cokolwiek idzie szybciej niż left join
to znaczy, że coś jest skopane z indeksami.

Albo, że teoria daleko odbiega od praktyki w przypadku MySQL
Magdalena Łach

Magdalena Łach AX senior developer

Temat: [MySQL] Jak inaczej napisać LEFT JOINa z warunkiem IS NULL

strona dotyczy sql servera (ale może się przyda?:)
http://www.sql-server-performance.com/tips/t_sql_where...

Using a NOT EXISTS

SELECT a.hdr_key
FROM hdr_tbl a
WHERE NOT EXISTS (SELECT * FROM dtl_tbl b WHERE a.hdr_key = b.hdr_key)

Using a LEFT JOIN

SELECT a.hdr_key
FROM hdr_tbl a
LEFT JOIN dtl_tbl b ON a.hdr_key = b.hdr_key
WHERE b.hdr_key IS NULL

Using a NOT IN

SELECT hdr_key
FROM hdr_tbl
WHERE hdr_key NOT IN (SELECT hdr_key FROM dtl_tbl)

In each case, the above query will return identical results. But, which of these three variations of the same query produces the best performance? Assuming everything else is equal, the best performing version through the worst performing version will be from top to bottom, as displayed above. In other words, the NOT EXISTS variation of this query is generally the most efficient.
Łukasz Schabek

Łukasz Schabek Architekt Rozwiązań

Temat: [MySQL] Jak inaczej napisać LEFT JOINa z warunkiem IS NULL

Maciej Filipiak:
Jezeli cokolwiek idzie szybciej niż left join
to znaczy, że coś jest skopane z indeksami.

Albo, że teoria daleko odbiega od praktyki w przypadku MySQL


http://explainextended.com/2009/09/18/not-in-vs-not-ex...
Bartosz Ratajczyk

Bartosz Ratajczyk MS SQL Developer

Temat: [MySQL] Jak inaczej napisać LEFT JOINa z warunkiem IS NULL

http://explainextended.com/2009/09/18/not-in-vs-not-ex...

Dzięki, ciekawy artykuł.

W moim przypadku szybciej zadziałało NOT EXISTS. Plan zapytania dla LEFT JOIN pokazał typ złączenia ALL, czyli robił skan na całej tabeli i olał dostępny indeks. Z prezentacji http://www.slideshare.net/ZendCon/sql-query-tuning-the... wynika, że mogą być dwa powody:
- Poor selectivity on an indexed field
- Too many records meet WHERE condition

Dla NOT EXIST indeks został użyty, czyli stawiam drugi punkt.

Następna dyskusja:

[MySQL] NOT IN a NULL'e




Wyślij zaproszenie do