Edycja: +1 działa w tej sytuacji, ponieważ okazuje się, że FILE_NUMBER
jest to liczba całkowita z zerową liczbą znaków. Lepszym rozwiązaniem tutaj dla ciągów jest dołączanie ''
(pusty ciąg), ponieważ dodanie wartości może wpływać na kolejność lub dla liczb, aby dodać coś, co jest stałe, ale zawiera funkcję niedeterministyczną, np sign(rand()+1)
. Pomysł „przełamania sortowania” jest nadal aktualny, po prostu moja metoda nie była idealna.
+1
Nie, nie mam na myśli, że się z czymkolwiek zgadzam, mam na myśli to jako rozwiązanie. Jeśli zmienisz zapytanie na, ORDER BY cj.FILE_NUMBER + 1
wówczas TOP 1
będą się one zachowywać inaczej.
Widzisz, z celem małego wiersza dla zamówionego zapytania, system spróbuje wykorzystać dane w celu uniknięcia operatora sortowania. Pozwoli to również uniknąć budowania tabeli skrótów, zakładając, że prawdopodobnie nie będzie musiał wykonywać zbyt wiele pracy, aby znaleźć ten pierwszy wiersz. W twoim przypadku jest to błędne - z grubości tych strzałek wygląda na to, że trzeba zużyć dużo danych, aby znaleźć pojedyncze dopasowanie.
Grubość tych strzałek sugeruje, że twój DOCUMENT_QUEUE
(DQ) stół jest znacznie mniejszy niż twój CORRESPONDENCE_JOURNAL
(CJ) stół. I że najlepszym planem byłoby sprawdzenie wierszy DQ aż do znalezienia wiersza CJ. Rzeczywiście, to właśnie zrobiłby Optymalizator Kwerend (QO), gdyby nie miał tego nieznośnego ORDER BY
, co jest ładnie wspierane przez indeks przykrywający CJ.
Więc jeśli ORDER BY
całkowicie upuściłeś , spodziewam się, że dostaniesz plan obejmujący zagnieżdżoną pętlę, iterującą po wierszach w DQ, szukającą w CJ, aby upewnić się, że wiersz istnieje. I z TOP 1
tym skończy się po wyciągnięciu jednego rzędu.
Ale jeśli faktycznie potrzebujesz pierwszego rzędu FILE_NUMBER
, możesz oszukać system, aby zignorował ten indeks, który wydaje się (niepoprawnie) tak pomocny, robiąc ORDER BY CJ.FILE_NUMBER+1
- co, jak wiemy, zachowa taką samą kolejność jak poprzednio, ale co ważne, QO nie. QO skupi się na przygotowaniu całości, aby operator Top N Sort mógł być zadowolony. Ta metoda powinna stworzyć plan, który zawiera operator skalowania obliczeniowego, aby obliczyć wartość dla zamówienia, oraz operator sortowania Top N, aby uzyskać pierwszy wiersz. Ale na prawo od nich powinieneś zobaczyć ładną zagnieżdżoną pętlę, wykonującą wiele poszukiwań na CJ. I lepsza wydajność niż przeglądanie dużej tabeli wierszy, które nie pasują do niczego w DQ.
Mecz Hash niekoniecznie jest okropny, ale jeśli zestaw wierszy, które zwracasz z DQ, jest znacznie mniejszy niż CJ (tak bym się spodziewał), to Hash Match będzie skanował znacznie więcej CJ niż potrzebuje.
Uwaga: Użyłem +1 zamiast +0, ponieważ optymalizator zapytań prawdopodobnie rozpozna, że +0 nic nie zmienia. Oczywiście to samo może dotyczyć +1, jeśli nie teraz, to w pewnym momencie w przyszłości.
DOCUMENT_ID
relację między dwiema tabelami (czy też każdy rekordCORRESPONDENCE_JOURNAL
zawiera pasujący rekordDOCUMENT_QUEUE
)?