Mam zapytanie na dużej tabeli, która wygląda następująco:
declare @myIdParam int = 1
select *
from myTable
where (@myIdParam is null or myTable.Id = @myIdParam)
Istnieje kilka podobnych warunków warunkowych w klauzuli where, a także wiele sprzężeń, ale jest to streszczenie.
W efekcie, jeśli @myIdParam ma wartość null, nie chcemy ograniczać wyników za pomocą tego parametru.
Nie jestem profesjonalistą DB, ale z moich testów wynika, że ta kontrola NULL jest wykonywana dla każdego rekordu i nie jest w żaden sposób zoptymalizowana.
Jeśli usunę sprawdzanie wartości NULL i założę, że parametr nie ma wartości NULL, zapytanie jest natychmiast zwracane. W przeciwnym razie zajmuje to do dziesięciu sekund.
Czy istnieje sposób na zoptymalizowanie tego, aby sprawdzanie było wykonywane tylko raz w czasie wykonywania?
sql-server
null
Mistagog
źródło
źródło
OPTION(RECOMPILE)
Odpowiedzi:
Jednym ze sposobów jest użycie dynamicznego SQL przy użyciu zerowego sprawdzenia, aby opcjonalnie dodać tę część klauzuli where.
źródło
sp_ExecuteSQL
i@vc_dynamicsql
parametr musi być aNVARCHAR
.Za każdym razem, gdy umieszczasz funkcję wokół kolumny `ISNULL (@var, table.col) ', na przykład, usuwasz zdolność SQL do używania indeksu. Jest to naprawdę najlepsza opcja, jeśli chcesz zachować ją w jednym zapytaniu.
W przeciwnym razie masz dwie opcje. Pierwszym z nich jest dynamiczny SQL, a odpowiedź @ Mystagogue jest do tego wystarczająca, w przeciwnym razie możesz wprowadzić dwa zapytania takie jak to:
Zarówno w tym formacie, jak i dynamicznym SQL, faktycznie otrzymujesz inny plan zapytań dla każdego zapytania (co potencjalnie da lepszą wydajność).
źródło
Cóż, możesz:
Należy jednak pamiętać, że ta
nullif()
funkcja jest zasadniczo zawijanacase
. To nie jest srebrna kula, która magicznie eliminuje,OR
a tym samym przyspiesza zapytanie.źródło
UNION
s. Kiedy miałem dokładnie to zadanie, wybrałem dynamiczny SQL.