Edycja: +1 działa w tej sytuacji, ponieważ okazuje się, że FILE_NUMBERjest 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 + 1wówczas TOP 1bę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 BYcał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 1tym 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_IDrelację między dwiema tabelami (czy też każdy rekordCORRESPONDENCE_JOURNALzawiera pasujący rekordDOCUMENT_QUEUE)?