Nie jest całkiem jasne, co masz na myśli przez
zachować kolejność elementów w tabeli tymczasowej
, ale jeśli chcesz uzyskać wynik sortowane według eserial
, to masz aby dodać ORDER BY eserial
do zapytania. Bez ORDER BY
wynikowe wiersze mogą zostać zwrócone w dowolnej kolejności. Dotyczy to każdej wybranej metody.
Więc, biorąc ostatnią kwerendy jako podstawa, będzie to wyglądać tak:
Select
lst.eserial
,lst.refdate
,app.CREATEDDATETIME
From
#mylist lst
Outer Apply
(
Select Top 1 rec.CREATEDDATETIME
From TableSource rec
Where lst.eserial=rec.ESERIAL And rec.CREATEDDATETIME<lst.refdate
Order By rec.CREATEDDATETIME Desc
) As app
ORDER BY lst.eserial;
Aby działać szybko i sprawnie dodać indeks do TableSource
na (ESERIAL, CREATEDDATETIME)
. Kolejność kolumn w indeksie jest ważna.
Ważne jest również, aby wiedzieć, czy istnieją inne kolumny, których używasz w zapytaniu OUTER APPLY
i jak ich używasz. Wspomniałeś kolumnę AREAID
w pierwszym wariancie pytania, ale nie w ostatnim wariancie. Jeśli masz więcej kolumn, to wyraźnie pokaż, w jaki sposób zamierzasz z nich korzystać, ponieważ właściwy indeks będzie od tego zależał. Indeks na (ESERIAL, CREATEDDATETIME)
wystarczy dla zapytania, które napisałem powyżej, ale jeśli masz więcej kolumn, może być wymagany inny indeks.
To pomogłoby także optymalizator jeśli zdefiniowano tabelę temp z PRIMARY KEY
:
Create Table #mylist
(
eserial nvarchar(35) Collate SQL_Latin1_General_CP850_CI_AS PRIMARY KEY,
refdate datetime
)
klucz podstawowy by stworzyć niepowtarzalny indeksu klastrowego.
Jeszcze jedna ważna uwaga. Jaki jest rodzaj i sortowania kolumn i CREATEDDATETIME
ESERIAL
w głównym TableSource
stole? Upewnij się, że typy i sortowanie kolumn w tabeli tymczasowej jest zgodne z główną tabelą TableSource
.Jeśli typ jest inny (varchar
vs. nvarchar
lub datetime
w porównaniu do date
) lub sortowanie jest inne, indeks nie może być użyty => będzie wolny.
Edit
użyć zwrotu „samą sekwencję jak tabeli temp” kilka razy w pytaniu, ale to naprawdę nie jest jasne, co masz na myśli przez nią. Twoje przykładowe dane nie pomagają rozwiązać niejednoznaczności. Nazwa kolumny eserial
również przyczynia się do zamieszania. Widzę dwa możliwe znaczenia:
- Zwraca wiersze z tabeli temp uporządkowanej według wartości w kolumnie
eserial
.
- Zwraca wiersze z tabeli tymczasowej w takiej samej kolejności, w jakiej zostały wstawione.
Moja oryginalna odpowiedź implikuje (1): zwraca wiersze z tabeli temp uporządkowanej według wartości w kolumnie eserial
.
Jeśli chcesz zachować kolejność wierszy, które zostały wstawione do tabeli, musisz w jakiś sposób wyraźnie zapamiętać tę kolejność. Najprostszą metodą jest dodanie kolumny IDENTITY
do tabeli tymczasowej i późniejszej kolejności w tej kolumnie. W ten sposób:
Create Table #mylist
(
ID int IDENTITY PRIMARY KEY,
eserial nvarchar(35) Collate SQL_Latin1_General_CP850_CI_AS,
refdate datetime
)
W ostatnim zapytaniu użyj ORDER BY lst.ID
.
Szczerze mówiąc, spodziewałem się, że metoda ZASTOSOWANIA ZEWNĘTRZNEGO zadziała najlepiej w ogólnym przypadku. Czy nie tworzysz żadnych indeksów na swoim stole tymczasowym? Czy możesz określić 'eserial' jako' PRIMARY KEY' w twoim utworze? –
@ BakonBits Próbowałem określić go jako klucz główny, ale ten sam wynik. Drugi kod jest szybszy prawie 10x. – L42
Czy próbowałeś z indeksem na ESERIAL, CREATEDDATETIME desc include (ITEMID), gdzie AREAID = "home" –