【问题标题】:SQL Query optimisation not existsSQL 查询优化不存在
【发布时间】:2012-09-18 03:06:57
【问题描述】:

我需要优化以下查询,有人可以帮忙吗?我知道是 Not Exists 部分导致了问题,因为它正在进行大规模的表扫描,但我是新手,谁能给点建议?

select count(*)
from Job j
where company = 'A'
and branch = 'Branch123'
and engineerNumber = '000123'
and ID > 60473
and not exists(
select JobNumber, Company, Branch
from OutboundEvents o
where o.JobNumber = j.JobNumber
    and o.branch = j.branch
    and o.company = j.company
    and o.Formtype = 'CompleteJob')

【问题讨论】:

  • 您能否分享一下作业和出站事件(包括索引)的架构,并在便于我们下载的地方发布实际执行计划(.sqlplan)?

标签: sql sql-server-2005 optimization


【解决方案1】:
create index [<indexname>] on [Job] (
    [company], [branch], [engineerNumber], [ID]) include ([JobNumber]);
create index [<indexname>] on [OutboundEvents] (
    [company], [branch], [JobNumber], [Formtype]);

您优化的不是查询,而是您优化的数据模型。从阅读Designing Indexes开始。

【讨论】:

  • 如果[JobNumber]也包含在第一个索引中会有什么不同吗?
  • @ypercube:是的,应该是,我没注意到
  • 请注意,添加这些索引以优化此特定查询不会考虑您的其余工作负载。如果您的写入:读取比率很高,您可能会为维护这些索引付出高昂的代价。我并不是说这会使这个答案出错,只是您需要考虑整个系统,而不仅仅是一个查询。这就是为什么我们不会盲目地遵循数据库引擎优化顾问的建议(或执行计划的建议,或缺失的索引 DMV),这些建议告诉我们根据有限和孤立的信息创建索引。
  • 同意:工作负载中的其他查询、提到的列的选择性、读/写比率都起作用。它的要点是解决方案不在查询的 文本 中(很少出现),而是在设计适当的数据模型中。我只是不喜欢给出无所不在的“视情况而定”的答案。
  • 是的,很公平。我不是要批评答案,只是补充它。它肯定比“它取决于”(或“这里,按照我喜欢的方式重写它”)有用得多。
【解决方案2】:

感谢大家的有益见解。我有很多东西要学:) 我设法使用这个查询将执行时间从 1 分钟 7 秒缩短到不到 1 秒:

select count(*)
from job
where company = 'A'
and branch = 'Branch123'
and EngineerNumber = '000123'
AND id> 60473
AND JobNumber not in(
    select Jobnumber from outboundevents b
    where b.company = 'A'
    AND b.Branch = 'Branch123'  
    and b.Formtype = 'CompleteJob'
    and jobnumber in (
        select jobnumber from Job
        where company = 'A'
        and branch = 'Branch123'
        and engineerNumber = '000123'
        and ID > 60473)
)

【讨论】:

  • 我也按照 Remus 的建议在桌子上放了一个索引。
  • 您应该知道,如果Jobnumber 可以为空,not in 的性能可能比not exists 更差,并且会产生令人惊讶的结果(子查询中存在 null 意味着不会返回任何行来自外部查询)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-10
  • 2014-02-04
  • 2014-11-16
  • 2011-06-22
相关资源
最近更新 更多