隐式转换是否强制索引扫描而不是查找?
Does implicit conversion force index scans instead of seeks?
我加入 table A
对抗 table 的 B
和 C
。所有三个 table 都具有相似的列和索引,并且 B
和 C
具有大致相同的行数。但是 A
和 B
在 nvarchar
列上有索引,而 C
在 varchar
列上有索引。
单独测试,加入 B
比加入 C
快 30-60 倍。 (4 秒对 2-4 分钟。)查看执行计划,B
使用索引查找,而 C
使用索引扫描。 C
上的连接的详细信息提到了 varchar
列的隐式转换,而 B
上的连接没有提到这种转换。 这就是它使用扫描而不是查找的原因吗?这可能是它这么慢的原因吗?(另一个潜在问题:C
上的索引扫描估计有执行次数为1次,但实际执行次数为8500次左右。)
C
是静态历史数据,因此如果有帮助,我可以更改列并重建索引。
是的,隐式转换可能会导致索引扫描而不是查找。数据被转换为具有较高 data type precedence 的数据类型。正如您在本例中所见,table c
的 VARCHAR
列被转换为 NVARCHAR
值。隐式转换可防止在转换期间丢失数据,即 NVARCHAR
列可以包含比 VARCHAR
多得多的不同字符,因此 VARCHAR
从 table C
的隐式转换确保 table C 中的所有值都将被保留。
进一步概述了有关特定隐式转换方案的详细信息 here。如果您可以选择并且这不会对其他地方产生任何负面影响,我建议将 table C
中的此列设为 NVARCHAR
数据类型。
我加入 table A
对抗 table 的 B
和 C
。所有三个 table 都具有相似的列和索引,并且 B
和 C
具有大致相同的行数。但是 A
和 B
在 nvarchar
列上有索引,而 C
在 varchar
列上有索引。
单独测试,加入 B
比加入 C
快 30-60 倍。 (4 秒对 2-4 分钟。)查看执行计划,B
使用索引查找,而 C
使用索引扫描。 C
上的连接的详细信息提到了 varchar
列的隐式转换,而 B
上的连接没有提到这种转换。 这就是它使用扫描而不是查找的原因吗?这可能是它这么慢的原因吗?(另一个潜在问题:C
上的索引扫描估计有执行次数为1次,但实际执行次数为8500次左右。)
C
是静态历史数据,因此如果有帮助,我可以更改列并重建索引。
是的,隐式转换可能会导致索引扫描而不是查找。数据被转换为具有较高 data type precedence 的数据类型。正如您在本例中所见,table c
的 VARCHAR
列被转换为 NVARCHAR
值。隐式转换可防止在转换期间丢失数据,即 NVARCHAR
列可以包含比 VARCHAR
多得多的不同字符,因此 VARCHAR
从 table C
的隐式转换确保 table C 中的所有值都将被保留。
进一步概述了有关特定隐式转换方案的详细信息 here。如果您可以选择并且这不会对其他地方产生任何负面影响,我建议将 table C
中的此列设为 NVARCHAR
数据类型。