Mamy generator SQL, który generalnie generuje instrukcje warunkowe SQL dla określonych pól (które dla celów dyskusji: oznaczymy jako myField
).
Jeśli myField
jest typu NVARCHAR
, możemy zrobić porównanie wspomnianej dziedzinie przeciwko ciąg tak: myField = 'foo'
.
Nie działa to jednak w przypadku pól typu NTEXT
. Zatem musimy zrobić porównanie z obsadą: CAST(myField as NVARCHAR(MAX)) = 'foo'
. To faktycznie zadziała, jeśli myField
jest typu NVARCHAR
lub NTEXT
.
Jaka jest skuteczność w wykonaniu wspomnianej obsady na polu, które jest już typu NVARCHAR
? Mam nadzieję, że SQL Server jest wystarczająco inteligentny, aby dynamicznie rozpoznawać, że myField
jest już tego typu NVARCHAR
(skutecznie zmieniając go CAST
w brak możliwości).
sql-server
performance
type-conversion
Paul White 9
źródło
źródło
Odpowiedzi:
Jeśli obsada kolumny ma dokładnie ten sam typ danych i długość, a predykat wyszukiwania jest dosłowny, rzeczywiście wydaje się, że go lekceważy lub traktuje jako brak możliwości i szuka indeksu na zasadzie równości.
Jeśli rzutowanie kolumny jest na ten sam typ danych, ale o większej długości, a predykatem wyszukiwania jest literał ciąg, powoduje skanowanie indeksu. Tego oczywiście należy unikać.
Jeśli rzutowanie kolumny jest tego samego typu danych i tej samej lub większej długości, a predykatem wyszukiwania jest zmienna lokalna, dodaje on obliczeniowy operator skalarny do planu wykonania. To wywołuje
GetRangeThroughConvert
i generuje zakres.Ten zakres służy do wyszukiwania indeksu i wydaje się dość wydajny
Kod testowy
źródło
Ogólnie rzecz biorąc,
CAST
zabije wydajność, ponieważ unieważnia jakiekolwiek użycie indeksów, jak pokazuje ostatni przykład Martina Smitha. Przesyłanie nanvarchar(max)
inną długość lub na inną oznacza inny typ danych: fakt, że wszystkonvarchar
jest nieistotne.Ponadto ważny jest również typ danych po prawej stronie porównania. Jeśli jest to zmienna lokalna lub parametr o innej długości, jedna strona będzie domyślnie przypisana
CAST
do najszerszego z 2 typów danych (patrz pierwszeństwo typu danych ).Zasadniczo, jeśli masz generalnego
CAST
nanvarchar(max)
to Bollix rzeczy. Zastanowiłbym się nad poprawieniem użycia,ntext
zanim dodamCAST
wszystko.Konwersja może nie być wyświetlana w planie zapytań. Zobacz artykuł na blogu Paula White'a
źródło
Tylko uwaga: przesyłanie w ten sposób, gdy Datecreated jest datetime
Nie ogranicza zdolności SQL do używania indeksów, jeśli indeksy istnieją, a jeśli nie istnieją, może spowodować zapisanie brakującego indeksu.
Podobnie, podczas rzucania od
int
celutinyint
lubbigint
doint
etc, funkcja obsada nie zatrzymuje SQL z użyciem indeksów IF Optymalizator wie, że operacja cast nie zmienia porządek z 2 porównywalnych typów danych.Oto kilka testów, które możesz uruchomić i zobaczyć aktualny plan za pomocą Adventureworks2008R2
źródło