【问题标题】:Is there any way to optimize this query?有没有办法优化这个查询?
【发布时间】:2021-05-17 14:25:20
【问题描述】:

我需要优化以下查询:

IF object_id('tempdb..#TAB001') IS NOT NULL  
DROP TABLE #TAB001;  

select *  
into #TAB001
from dbo.uvw_TAB001   
where 1 = 1  
and isnull(COD_CUSTOMER,'') = isnull(@cod_customer,isnull(COD_CUSTOMER,''))  
and isnull(TAXCODE,'') = isnull(@taxcode, isnull(TAXCODE,''))   
and isnull(SURNAME,'') = isnull(@surname,isnull(SURNAME,''))   
and isnull(VATCODE,'') = isnull(@vatCode,isnull(VATCODE,''))

目标是提高此查询的性能。 目前速度很快,但我想加快速度。

此查询具有可选参数,需要对其进行查询,无论设置了 all 还是 1 个参数,都在尽可能短的时间内返回结果。

【问题讨论】:

  • 那么无论您做什么,都不要使用ISNULL 来节省一些输入,这是确保不能使用索引的好方法。请参阅this 和文章的其余部分,了解做什么好。
  • 您可以将索引添加到基础表。添加索引通常由数据库管理员完成。这取决于 COD_CUSTOMER、TAXCODE、SURNAME、VATCODE 是从视图中的基础表中选择的列还是计算的列。您可以通过编写视图来验证。如果它们被选中,我将为基础表的每一列添加 1 个索引。 SQL Server 应该处理这些索引的合并连接,或者至少选择它认为最优化的索引组合。您可以通过查看 SSMS 中的估计执行计划来确认 SQL Server 是否使用索引。

标签: sql-server performance


【解决方案1】:

您在这里所拥有的称为"catch-all""kitchen sink" 查询,有时需要一点帮助。

首先,你需要摆脱那些ISNULLs;他们使查询成为非 SARGable。另外,我建议去掉SELECT * 并将查询限制在您需要的列。

然后,最后,我们可以在查询中添加OPTION (RECOMPILE);为什么在我上面链接的文章中讨论过。这将为您提供以下信息:

SELECT * --Replace with Column Names
INTO #TAB001 --Do you actually need to do this?
FROM dbo.uvw_TAB001
--Removed WHERE 1 = 1 as it's always true, thus pointless
WHERE (COD_CUSTOMER = @cod_customer OR @cod_customer IS NULL)
  AND (TAXCODE = @taxcode OR @taxcode IS NULL)
  AND (SURNAME = @surname OR @surname IS NULL)
  AND (VATCODE = @vatCode OR @vatCode IS NULL)
OPTION (RECOMPILE);

注意我假设当一个变量(例如@cod_customer)的值为NULL时,你的意思是该变量应该被“忽略”并且不匹配NULL

如果您确实想要{Column} = @{Variable} 包括NULL,请改用以下格式的SQL:

({Column} = @{Variable} OR ({Column} IS NULL AND @{Variable} IS NULL))

【讨论】:

  • 您好拉努,感谢您的支持。阅读您在链接 "catch-all" 中插入的文档,它说“在大型表上,可能会导致查询性能非常差。”。尽管如此,cpu_time 减少了 -99.24%,total_elapsed_time 减少了 -98.17%。
  • 可以并不意味着,@VirtualCom。虽然盖尔在OPTION (RECOMPILE) 上的具体文章在她here 的第二篇文章中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-04
  • 2013-01-01
  • 1970-01-01
  • 2021-10-27
相关资源
最近更新 更多