gpt4 book ai didi

sql - 为什么使用 phone = N'123 4' slower than phone = ' 1234' 查询?

转载 作者:行者123 更新时间:2023-12-02 03:37:47 28 4
gpt4 key购买 nike

我有一个字段是 varchar(20)

执行此查询时,速度很快(使用索引查找):

SELECT * FROM [dbo].[phone] WHERE phone = '5554474477'

但是这个很慢(使用索引扫描)。
SELECT * FROM [dbo].[phone] WHERE phone = N'5554474477'

我猜如果我将字段更改为 nvarchar,那么它将使用索引查找。

最佳答案

因为 nvarchar有更高 datatype precedencevarchar所以它需要将该列隐式转换为 nvarchar这可以防止索引查找。

在某些排序规则下,它仍然可以使用查找并推送 cast进入针对搜索匹配的行的剩余谓词(而不是需要通过扫描对整个表中的每一行执行此操作),但大概您没有使用这种排序规则。

整理对此的影响如下所示。当使用 SQL 排序规则时,您会得到一个扫描,对于 Windows 排序规则,它调用内部函数 GetRangeThroughConvert 并且能够将其转换为搜索。

CREATE TABLE [dbo].[phone]
(
phone1 VARCHAR(500) COLLATE sql_latin1_general_cp1_ci_as CONSTRAINT uq1 UNIQUE,
phone2 VARCHAR(500) COLLATE latin1_general_ci_as CONSTRAINT uq2 UNIQUE,
);

SELECT phone1 FROM [dbo].[phone] WHERE phone1 = N'5554474477';
SELECT phone2 FROM [dbo].[phone] WHERE phone2 = N'5554474477';

enter image description here
SHOWPLAN_TEXT在下面

查询 1
  |--Index Scan(OBJECT:([tempdb].[dbo].[phone].[uq1]),  WHERE:(CONVERT_IMPLICIT(nvarchar(500),[tempdb].[dbo].[phone].[phone1],0)=CONVERT_IMPLICIT(nvarchar(4000),[@1],0)))

查询 2
  |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1005], [Expr1006], [Expr1004]))
|--Compute Scalar(DEFINE:(([Expr1005],[Expr1006],[Expr1004])=GetRangeThroughConvert([@1],[@1],(62))))
| |--Constant Scan
|--Index Seek(OBJECT:([tempdb].[dbo].[phone].[uq2]), SEEK:([tempdb].[dbo].[phone].[phone2] > [Expr1005] AND [tempdb].[dbo].[phone].[phone2] < [Expr1006]), WHERE:(CONVERT_IMPLICIT(nvarchar(500),[tempdb].[dbo].[phone].[phone2],0)=[@1]) ORDERED FORWARD)

在第二种情况下,计算标量 emits the following values
Expr1004 = 62
Expr1005 = '5554474477'
Expr1006 = '5554474478'

计划中显示的搜索谓词在 phone2 > Expr1005 and phone2 < Expr1006 上所以从表面上看,它会排除 '5554474477'但旗帜 62意味着这确实匹配。

关于sql - 为什么使用 phone = N'123 4' slower than phone = ' 1234' 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54540928/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com