sql - Where语句中的嵌套循环杀死性能

标签 sql t-sql

在 WHERE 子句中使用嵌套循环时,我遇到了严重的性能问题。

当我按原样运行以下代码时,需要几分钟的时间。诀窍是,如果 report_id 为 NULL,我将使用 WHERE 子句提取所有数据,但如果我设置,则仅提取某些report_id它们在参数字符串中。

函数[fn_Parse_List]将VARCHAR字符串(例如'123,456,789')转换为一个表,其中每行都是整数形式的数字,然后在IN 子句。

当我使用 report_id = '456' (虚线部分)运行下面的代码时,代码需要几秒钟的时间,但传递临时表并在 WHERE 子句中使用 SELECT 语句会杀死它.

alter procedure dbo.p_revenue

(@report_id varchar(max) = NULL)

as

select cast(value as int) Report_ID 
into #report_ID_Temp 
from [fn_Parse_List] (@report_id)

SELECT * 
FROM BIGTABLE
where @report_id is null 
   or a.report_id in (select Report_ID from #report_ID_Temp)
--Where @report_id is null or a.report_id in (456)


exec p_revenue @report_id = '456'

有没有办法优化这个?我尝试对表 #report_ID_Temp 进行 JOIN,但仍然需要同样长的时间,并且当 report_id 为 NULL 时不起作用。

最佳答案

您违反了三项不同的规则。

  1. 如果您需要两个查询计划,则需要两个查询:OR 不会为您提供两个查询计划。 IF 确实如此。
  2. 如果您有临时表,请确保它具有主键和任何适当的索引。在您的情况下,您需要一个 ALTER TABLE 语句来添加主键聚集索引。或者您可以CREATE TABLE首先声明结构。
  3. 如果您认为 fn_Parse_List 是个好主意,那么您还没有阅读足够的内容 Sommarskog

关于sql - Where语句中的嵌套循环杀死性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34866385/

相关文章:

sql - Laravel 按条件 eloquent 或 sql 排序

mysql - 如何创建一个复杂的查询,将条件与 2 个表相加?

sql查找每个月最小日期的行

SQL - 从上面的行返回值

sql - 连接具有两个任务列表和用户列表的表

MYSQL查询查找成对行之间的差异?

c# - 序列化和散列

sql - 返回 T-SQL 中 2 个日期之间的工作日数

SQL查询: find all devices that have ALL of the Ids passed in

t-sql - 基于时差的记录