【发布时间】:2015-03-18 23:51:58
【问题描述】:
我有一条 SQL 语句来提取记录。某些员工可以访问某些记录。人员安全都在一个单独的过程中完成,并附加到搜索 SQL 子句的 where 子句中。
简化示例:
select
o.id, o.staff.id
from
Orders o
where
staffid = 100
or orderid in (select orderid from schedule where staffid = 5)
对
select
o.id, o.staff.id
from
Orders o
where
staffid = 100 or orderid in (1, 2, 3, 4, 5, 6, 7, 8)
嵌套的 sql select orderid from schedule where teamid = 5 运行时间为 1 秒。如果将结果粘贴到其位置,则主查询将在 2 秒内运行。如果您运行顶级 SQL,则需要一分钟多的时间才能运行。出于某种原因,您如何告诉 SQL 先运行嵌套选择而不将其分解为临时表?
来自您所有建议的更多信息:
我的 SQL 也有OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY。删除后,查询速度很快。它可以在 1 秒内返回 1800 条记录,但请求 10 条记录需要 40 秒。
如果我将订单更改为staffid,它也会运行得很快。 order by 和 fetch next 的组合导致 SQL 运行不同的执行计划。由于Where 子句位于软件的单独部分中,我无法更改order by,它正在扼杀性能。
【问题讨论】:
-
teamid = 5或staffid = 5在子查询中? -
在“实际执行计划”开启的情况下运行查询,看看它是否建议任何索引。此外,通过简化示例而不共享架构,您可能隐藏了问题的实际原因。
-
执行计划没有显示索引提示。查询成本分为 35/65,这很奇怪,因为运行时间是 2 秒 vs 45 秒。
-
Tanner,很好,我开始删除我的 SQL 的某些方面,看看它是否运行得更快。发生 OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;导致它变慢。如果我删除这两个查询都很快。
标签: sql sql-server optimization