2012-06-05 14 views
6

Mam dwie tabele:Kiedy lepiej nie używać połączenia wewnętrznego?

table1 (id, name, connte) 
table2 (id, name, connte) 

są podłączone poprzez table1.connte i table2.connte. A każdy z nich zawiera 100 rekordów.

Teraz jeśli chcę usunąć rekord z Tabela1 z ID = 20 oraz jej odpowiednimi dzieci w Table2, lepiej jest wykonać następujące czynności:

DELETE d1,d2 FROM table1 d1 INNER JOIN table2 d2 ON d1.connte= d2.connte WHERE d1.id = 20 

lub co następuje:

select connte from table1 where id = 20 
    --Store connte in a variable say aabc-- 
    delete from table2 where connte = aabc -> execute this first 
    delete from table1 where id = 20 -> execute this second 

Jeśli istnieje tylko jeden rodzic i jedno dziecko dla rekordu, który chcę usunąć (tutaj table1.id = 20), czy nie jest drogie wykonywanie łączenia wewnętrznego dla całej tabeli?

Używam tego zapytania z JAVA (tak JDBC), więc czy jest droższe (z punktu widzenia wydajności) uruchamianie wielu zapytań lub sprzężenia wewnętrznego dla wyżej wymienionego warunku?

UWAGA: Zakładając, że tabele nie zawierają więzów integralności. Tak więc nie używam usuwania kaskadowego.

Odpowiedz

6

Prawdopodobnie będzie to szybsze w jednym zapytaniu niż w dwóch. Zasadniczo próbujesz zrobić optymalizację samodzielnie, zamiast pozwolić DBMS to zrobić, a ogólnie DBMS "są naprawdę dobre w tego rodzaju rzeczy.

Poza tym prawdopodobnie nie będziesz musiał się martwić wydajnością usuwania tak małych tabel. 100 x 100 rzędów jest nadal bardzo małe, więc Twój DBMS powinien być w stanie obsłużyć to bez problemu.

+0

Hmm..ok, ale co, kiedy mam, powiedzmy sto tysięcy lub milion rekordów? Które podejście byłoby wtedy lepsze dla mojego wspomnianego stanu? – Harke

+0

W dalszym ciągu zalecałbym, aby DBMS go obsługiwał. Wie, jak zrobić te optymalizacje lepiej, niż to możliwe. – Oleksi

+0

Czy jest jakiś sposób mogę wiedzieć, jak działa wewnętrzne sprzężenie? Czy nie przyłączysz się do dwóch tabel z milionem nagrań każdy, zabiera czas? (nawet po filtrowaniu z klauzulą ​​ON istnieje możliwość, że istnieje wiele rekordów do dołączenia) – Harke

3

Najlepszym sposobem na zrobienie tego jest uruchomienie planu wyjaśnień dla obu zapytań w DBMS, a dane wyjściowe dają takie dane, jak szacunki I/O itp. Ogólnie, w każdej chwili masz pytanie, co będzie bardziej Wydajny z perspektywy DBMS, patrząc na plany zapytań i kosztorysy to twoja najlepsza broń.

SET showplan on 

powinien działać na serwerze SQL. Oto MSDN documentation, może być potrzebna nieco inna składnia w zależności od DBMS. Szacowanie kosztów na I/O jest prawdopodobnie tym, na czym najbardziej Ci zależy.

dla MySQL, wygląda na to, można użyć

EXPLAIN SELECT * FROM some_table 

Here is a tutorial na analizie zapytań wykorzystujących Explain.

Ogólnie rzecz biorąc, Oleksi ma rację; większość optymistów jest bardzo dobra w tego rodzaju rzeczach i ręczne tworzenie tabeli tymczasowej nie przyniesie ci zbyt dużego zakupu. Wiele razy plan zapytania optymalizatora będzie wymagał utworzenia tabeli tymczasowej.

W przypadku kwerendy usuwania jedną ważną rzeczą dla zapewnienia szybkości jest to, że klauzula delete korzysta z indeksowanych parametrów, co nie powoduje pełnego skanowania tabeli. Explain/Showplan powie Ci, jaki typ skanowania wykonuje twoje zapytanie i jakie indeksy używa. Generalnie chcesz uniknąć skanowania pełnych tabel.

1

W serwerze Sql nie można usunąć z dwóch tabel w jednej instrukcji usuwania (bez wyzwalacza lub usuwania kaskadowego).

+0

Tak, w moim przypadku (który nie ma integralności referencyjnej i żadnych wyzwoleń), tylko drugi warunek jest możliwy? – Harke

+0

Tak, dla serwera SQl, Mysql może być inny – HLGEM

0

Dlaczego nie brać pod uwagę używania kluczy obcych i usuwania kaskadowego? Jeśli ustawisz stół poprawnie, po prostu musisz usunąć rodzica, a następnie dziecko zostanie automatycznie zadbane. Zobacz ten link When/Why to use Cascading in SQL Server?

Powiązane problemy