sql - 为什么相同类型的查询的查询成本如此不同?
问题描述
这是我在 SQL Server 2008 中的 SQL 查询。
三个相同的查询,使用不同的方法
Declare @UploadDetailID nvarchar(500) = '62703,62709,67161,67167,74580,76728,76774,76777,89001,116048,602337,52674,626855,626863,626877,626862,626874,626861,626873,626857,626860,626872,636929,636938, 636925,636937,636924,636920,636922,636934,636923,644566,644574,644565,644577,644564,644563,644561,646566,646578,646567,646575,646565,646562,646564,653093,653096,653103';
Begin
select top 500 *
from SignatureDetail
where (Case When @UploadDetailID = '' then 1
When ','+@UploadDetailID+',' like '%,' + ltrim(UploadDetailID) + ',%' then 1
Else 0
End) = 1
select top 500 *
from SignatureDetail
where ',' + @UploadDetailID + ',' like '%,' + ltrim(UploadDetailID) + ',%'
select top 500 *
from SignatureDetail
where (Case when ',' + @UploadDetailID + ',' like '%,' + ltrim(UploadDetailID) + ',%' then 1 else 0 End) = 1
End
以下是查询费用:
(1)第一个查询Case
和两个When
条件只占查询成本的 4%
select top 500* from SignatureDetail where
(Case when @UploadDetailID='' then 1
When ','+@UploadDetailID+',' like '%,'+ltrim(UploadDetailID)+',%' then 1
else 0 End)=1
(2)无条件第二次查询Case
占总查询成本的48%
select top 500* from SignatureDetail where ','+@UploadDetailID+',' like '%,'+ltrim(UploadDetailID)+',%'
(3)第三次查询Case
和一个When
条件也占总查询成本的 48%
select top 500* from SignatureDetail where (Case when ','+@UploadDetailID+',' like '%,'+ltrim(UploadDetailID)+',%' then 1 Else 0 End)=1
为什么第二个和第三个查询占用了总查询成本这么多?
解决方案
您在以下几个方面混淆了查询分析器:
您要么选择所有行,要么选择一组 ID。
您正在查找字符串匹配,而不是直接获取 ID。
我建议你有两个查询:
查询 1 - 如果没有 ID,只需从表中选择。
查询 2 - 如果您有一个 ID 列表,请用它们制作一个临时表,以便您可以与另一个表进行 JOIN 以实现完全匹配。您将获得比字符串匹配更好的性能。较新版本的 SQL Server 甚至可以使用 STRING_SPLIT 自动为您完成
参考: https ://docs.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql?view=sql-server-2017
推荐阅读
- amazon-web-services - Amazon AWS Lambda 错误:上传过大:1070404 字节超出了 1048576 的限制
- powershell - Powershell - 比较两个数组并将第二个数组中的额外数据写入第一个数组
- c++ - 如果将 DLL 移动到不同的位置,Windows DLL 函数的行为会有所不同
- excel - 如何复制名称中带有波兰字母的表格[VBA]?
- scala - 使用 val object(arg) = object 为 arg 赋值
- c - \b 不工作。\\ 给出了错误的输出。为什么 putchar() 在 while 范围内的行为与在 if 子句中的行为不同?
- excel-formula - Excel vlookup 在其他列上继续
- linux - 在 Oracle Virtual 框中为桥接适配器设置静态 IP 地址
- elasticsearch - Elasticsearch 结果大小限制
- php - 如何在条带上创建计划并返回带有前缀 plan_ 的计划 ID