Próbuję uruchomić następujące polecenie SQL w Oracle, a to trwa wieki, aby uruchomić:Optymalizacja kwerendę wybierającą, która działa powoli na Oracle, która biegnie szybko na SQL Server
SELECT orderID FROM tasks WHERE orderID NOT IN
(SELECT DISTINCT orderID FROM tasks WHERE
engineer1 IS NOT NULL AND engineer2 IS NOT NULL)
Jeśli uruchomić tylko sub-część, która jest w klauzuli IN, który działa bardzo szybko w Oracle, czyli
SELECT DISTINCT orderID FROM tasks WHERE
engineer1 IS NOT NULL AND engineer2 IS NOT NULL
Dlaczego cała wypowiedź na taki długi czas w Oracle? W SQL Server cała instrukcja działa szybko.
Czy istnieje również prostsza/inna/lepsza instrukcja SQL, której powinienem użyć?
Nieco więcej szczegółów na temat problemu:
- Każde zamówienie jest wykonana z wielu zadań
- Każde zamówienie będzie alokowanych (jednego lub większej liczby jego zadania będzie musiał engineer1 i engineer2 ustawiony) lub zlecenie może być nieprzydzielone (wszystkie jego zadania mają wartości puste dla pól inżynierskich)
- Próbuję znaleźć wszystkie identyfikatory zamówień, które są nieprzydzielone.
W przypadku, gdy robi różnicę, w tabeli jest ~ 120 tys. Wierszy, a 3 zadania na zamówienie, czyli ~ 40k różnych zamówień.
Odpowiedzi na odpowiedzi:
- wolałbym SQL, który działa zarówno w SQL Server i Oracle.
- Zadania zawierają tylko indeks w identyfikatorze zlecenia i identyfikatorze zadania.
- Próbowałem wersję instrukcji NOT EXISTS, ale trwało to ponad 3 minuty, zanim ją anulowałem. Być może potrzebujesz wersji JOIN instrukcji?
- Istnieje również tabela "zamówienia" z kolumną orderID. Ale próbowałem uprościć pytanie, nie dołączając go do oryginalnego oświadczenia SQL.
myślę, że w oryginalnym SQL sub-zapytania jest uruchamiany za każdym razem dla każdego wiersza w pierwszej części zestawienia SQL - mimo że jest statyczna i powinna wystarczy uruchomić raz?
Wykonywanie
ANALYZE TABLE tasks COMPUTE STATISTICS;
wykonana moja oryginalna instrukcja SQL wykonać znacznie szybciej.
Chociaż nadal jestem ciekawy, dlaczego muszę to zrobić, i czy/kiedy będę musiał uruchomić go ponownie?
Statystyki dać kosztowego optymalizatora informacje Oracle że potrzebnych do określenia efektywności różnych planów wykonania: dla przykład liczba rowsin stół, średniej szerokości wierszy, najwyższa i najniższe wartości na kolumnę, liczba różnych wartości na kolumnę, klasterowanie współczynnik indeksów itp.
W niewielkiej bazie danych wystarczy ustawić pracę, aby gromadzić statystyki każdej nocy i pozostawiać ją w spokoju. W rzeczywistości jest to domyślnie poniżej 10g. W przypadku większych implementacji zwykle trzeba zmierzyć stabilność planów wykonania w odniesieniu do sposobu, w jaki zmieniają się dane , co jest trudnym zadaniem.
Oracle ma również funkcję o nazwie "dynamiczne próbkowanie", która jest używana do tabel próbek w celu ustalenia odpowiednich statystyk w czasie wykonywania. Jest on znacznie częściej wykorzystywany w magazynach danych, w których obciążenie związane z próbką jest większe od potencjalnego zwiększenia wydajności o dla długoterminowego zapytania o wartości .
Nigdy nie zrozumiem, dlaczego programiści tak często umieszczają DISTINCT w swoich klauzulach IN. Czy 7 w (1, 1, 1, 1, 2, 2, 2, 7)? Czy 5? Odpowiedź nie zmienia się, jeśli moja lista jest (1, 2, 7). Kiedy uruchamiam to w Oracle, po prostu ignoruje wyraźne ... CBO zdaje sobie sprawę, że nie ma żadnej wartości. –