SEa*_*986 4 performance datatypes execution-plan type-conversion sql-server-2014
鉴于以下脚本,我可以看到隐式转换和数据类型优先级对查询计划有负面影响
-- create objects
CREATE DATABASE ConvertTest
GO
USE ConvertTest
GO
CREATE TABLE Person
(
VarcharId NVARCHAR(4),
IntId INT
)
-- insert data
INSERT INTO Person
SELECT TOP 1000
CONVERT(NVARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id)),
ROW_NUMBER() OVER (ORDER BY a.object_id)
FROM sys.objects a
CROSS JOIN sys.objects b
-- create indexes
CREATE INDEX IX_Varchar ON Person
(
VarcharId,
IntId
)
CREATE INDEX IX_Int ON Person
(
IntId,
VarcharId
)
DECLARE @id NVARCHAR(4) = 100
-- statement 1
SELECT * FROM Person WHERE VarcharId = @id
-- index seek
-- statement 2
SELECT * FROM Person WHERE IntId = @id
-- index seek
GO
DECLARE @id INT = 100
-- statement 3
SELECT * FROM Person WHERE VarcharId = @id
-- index scan
-- statement 4
SELECT * FROM Person WHERE IntId = @id
-- index seek
Run Code Online (Sandbox Code Playgroud)
查询 3 将 VarcharId 列隐式转换为 int(具有更高的优先级),这会导致谓词不可 SARGable,从而导致表扫描。
然而,当我运行类似的测试时,我没有得到我预期的结果:
-- create objects
CREATE DATABASE ConvertTest2
GO
USE ConvertTest2
GO
CREATE TABLE Ids
(
NvarId NVARCHAR(4),
VarId VARCHAR(4)
)
-- insert data
INSERT INTO Ids
SELECT TOP 1000
CONVERT(NVARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id)),
CONVERT(VARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id))
FROM sys.objects a
CROSS JOIN sys.objects b
-- create indexes
CREATE INDEX IX_NvarId ON Ids
(
NvarId,
VarId
)
CREATE INDEX IX_VarId ON Ids
(
VarId,
NvarId
)
DECLARE @id NVARCHAR(4) = N'10'
SELECT * FROM Ids WHERE NvarId = @id
SELECT * FROM Ids WHERE VarId = @id
GO
DECLARE @id VARCHAR(4) = '10'
SELECT * FROM Ids WHERE NvarId = @id
SELECT * FROM Ids WHERE VarId = @id
Run Code Online (Sandbox Code Playgroud)
所有四个查询都显示索引查找(尽管查询二通过计算机标量的嵌套循环运行查找)
鉴于 NVARCHAR 的数据类型优先级高于 VARCHAR,我预计会看到 VarId 列隐式转换为 VARCHAR,从而导致表扫描。
在 varchar / nvarchar 类型之间转换时,数据类型优先级为何/如何不同?
自从我发帖以来,我已经成功地在这里找到了答案。
对谓词中的列执行从 VARCHAR 到 NVARCHAR 的隐式转换时,是否执行扫描或查找的行为取决于排序规则设置。
较旧的旧排序规则设置将导致索引扫描,而较新的排序规则设置将导致查找
| 归档时间: |
|
| 查看次数: |
4353 次 |
| 最近记录: |