インデックスの暗黙的な変換がパフォーマンスに影響することを読んだので、次のクエリではその意味で
select count(*)
from fpc
where SKey in (201701, 201702)
sKeyはint型なので、上記のクエリを
select count(*)
from fpc
where SKey in ('201701', '201702')
パフォーマンスが低下します。
私はこれを数百万行あるテーブルでテストしました。問題は、実行計画と時間に違いが見られなかった理由です。
SKeyに非クラスター化列ストアインデックスがあります。
SKeyごとに約2000万行あり、約100の異なるSKeyがあります
暗黙的な変換の問題は、インデックスの効率的な使用を妨げることです。正しい比較値を取得するために関数を列に適用する必要がある場合、その列でのインデックスシークは検索に使用できません。
ただし、SQL Serverは、異なるタイプの値を比較する必要があるときに、変換する値を決定する必要があります。 Data Type Precedence ルールに基づいてこれを行います。
そのページを見ると、integer
の値がvarchar
の値よりも優先されていることがわかります。したがって、varchar
値は変換される値です。
提示した例では、インデックス付きの列はinteger
列であり、ハードコードされた値はvarchar
(またはchar
、またはnvarchar
-all integer
)よりも優先順位が低くなります。
したがって、ハードコードされた値は整数に変換されます。列は変換されないため、引き続きインデックスを使用できます。
注:これはこれに入る唯一の要因ではありません。たとえば、同じ「ファミリー」にある異なるデータ型(たとえば、int
とbigint
)間の変換では、インデックス付けされた列のデータ型に関係なく、インデックスシークが可能です。
このため、可能な限りデータ型を一致させるか、必要に応じてインデックス付けされていないデータに対して明示的な変換を使用する必要があります。変換プロセスを制御することにより、通常は問題を回避できます。
個人的には-この優先順位は長い間煩わしいものでした。数値と比較する必要がある文字値がある場合、明示的に変換を実行しない限り、SQL Serverは文字値(常に有効な数値表現とは限らない)を変換する代わりに数値に変換しようとします数値(常に有効な文字表現が必要です)。はぁ。
Bob Klimes はいくつかの関連記事を指摘しました: