Sql 多连接的慢速查询-扩展魔法药丸?

Sql 多连接的慢速查询-扩展魔法药丸?,sql,sql-server,sql-execution-plan,query-planner,Sql,Sql Server,Sql Execution Plan,Query Planner,我有一个需要20分钟才能运行的查询,尽管我为where子句中的每一列以及连接的每一列都有一个索引: 现在你要说的是,嗯,duh,当然这会更快一些——问题是,ModelImport表只包含351条记录。这意味着如果我将上面的查询拆分为351个查询,每个查询都有自己的where子句来表示不同的模型代码,那么我可以在大约175秒或2.9分钟内得到100%的查询结果。这大大加快了速度。这告诉我,宽开放查询中的某些内容非常低效,并且查询计划很糟糕 这是添加了和mi.ModelCode='3FBK5'的my

我有一个需要20分钟才能运行的查询,尽管我为where子句中的每一列以及连接的每一列都有一个索引:

现在你要说的是,
嗯,duh,当然这会更快一些
——问题是,ModelImport表只包含351条记录。这意味着如果我将上面的查询拆分为351个查询,每个查询都有自己的where子句来表示不同的模型代码,那么我可以在大约175秒或2.9分钟内得到100%的查询结果。这大大加快了速度。这告诉我,宽开放查询中的某些内容非常低效,并且查询计划很糟糕

这是添加了
和mi.ModelCode='3FBK5'
的my


查看我的后,有什么想法可以加快速度吗?

您是否可以消除一些连接,因为您没有从这些表中选择任何内容或对这些表应用任何where条件,例如。,skm和mi?

是否可能删除一些连接,因为您没有从这些表中选择任何内容,也没有对这些表应用任何where条件,例如skm和mi?

没有表模式和大小,要给出准确的答案有点困难,但这里有一些更新需要尝试

  • 使用group by而不是distinct
  • 不要在select结果中使用*(特别是使用distinct),而是提供要返回的特定列列表
  • 避免where子句中的“或”语句(可能改用ISNULL)
以下是这些更新后查询的外观(尽管可能需要添加skto中的其他列)

选择skt.VCDRAWING\u REG\u NO,
skb.NDRAWING\u组织号,
skb.NDRAWING组织版次号,
skb.CAPPLY开始日期,
skb.CAPPLY_结束日期,
skto.NDRAWING\u系统\u编号
来自SPM_ABS_TRANBASE skt
加入SPM_ABS_基地skb
skt.NDRAWING\u ORG\u REV\u NO=skb.NDRAWING\u ORG\u REV\u NO
和skt.NDRAWING_ORG_NO=skb.NDRAWING_ORG_NO
加入SPM_ABS_型号skm
skb.NDRAWING\u ORG\u REV\u NO=skm.NDRAWING\u ORG\u REV\u NO
和skb.NDRAWING_ORG_NO=skm.NDRAWING_ORG_NO
加入SPM_ABS_TRANOPT skto ON
skt.NDRAWING\u SYSTEM\u NO=skto.NDRAWING\u SYSTEM\u NO
加入模型导入
skm.CMODEL=mi.ModelCode
其中ISNULL(skb.CAPPLY_START_DATE,DATEADD(day,2,GETDATE())=DATEADD(day,-2,GETDATE())
按skt.VCU图纸注册号分组,
skb.NDRAWING\u组织号,
skb.NDRAWING组织版次号,
skb.CAPPLY开始日期,
skb.CAPPLY_结束日期,
skto.NDRAWING\u系统\u编号

如果没有表格模式和大小,要给出准确的答案有点困难,但这里有一些更新可以尝试

  • 使用group by而不是distinct
  • 不要在select结果中使用*(特别是使用distinct),而是提供要返回的特定列列表
  • 避免where子句中的“或”语句(可能改用ISNULL)
以下是这些更新后查询的外观(尽管可能需要添加skto中的其他列)

选择skt.VCDRAWING\u REG\u NO,
skb.NDRAWING\u组织号,
skb.NDRAWING组织版次号,
skb.CAPPLY开始日期,
skb.CAPPLY_结束日期,
skto.NDRAWING\u系统\u编号
来自SPM_ABS_TRANBASE skt
加入SPM_ABS_基地skb
skt.NDRAWING\u ORG\u REV\u NO=skb.NDRAWING\u ORG\u REV\u NO
和skt.NDRAWING_ORG_NO=skb.NDRAWING_ORG_NO
加入SPM_ABS_型号skm
skb.NDRAWING\u ORG\u REV\u NO=skm.NDRAWING\u ORG\u REV\u NO
和skb.NDRAWING_ORG_NO=skm.NDRAWING_ORG_NO
加入SPM_ABS_TRANOPT skto ON
skt.NDRAWING\u SYSTEM\u NO=skto.NDRAWING\u SYSTEM\u NO
加入模型导入
skm.CMODEL=mi.ModelCode
其中ISNULL(skb.CAPPLY_START_DATE,DATEADD(day,2,GETDATE())=DATEADD(day,-2,GETDATE())
按skt.VCU图纸注册号分组,
skb.NDRAWING\u组织号,
skb.NDRAWING组织版次号,
skb.CAPPLY开始日期,
skb.CAPPLY_结束日期,
skto.NDRAWING\u系统\u编号

所有这些索引是在单列上,还是在一个连接中的所有列上都是复合索引?如果为任何给定连接连接多个列,并且单个where子句包含多列,则它们是复合索引。否则它们是单表。我们需要CREATE TABLE语句,请参见。。如果没有这些,它仍然在使用。另外,如果将SQL重写为使用
EXISTS(…)
的话,这可能会更快,例如,因为此查询是一种爆炸式的(“大量”添加记录的连接)到内爆式(不同的删除记录)扫描/过滤方法。。查看查询中将在何处使用EXISTS()?抱歉,但是有数十万条记录,我不能为所有这些创建语句,这是由于记录的高容量造成的。所有这些索引是在单列上还是在复合列上,比如,连接中的所有列?如果为任何给定连接连接多个列,并且单个where子句包含多个列,则它们是复合的。否则它们是单表。我们需要CREATE TABLE语句,请参见。。如果没有这些,它仍然在使用。另外,如果将SQL重写为使用
EXISTS(…)
的话,这可能会更快,例如,因为此查询是一种爆炸式的(“大量”添加记录的连接)到内爆式(不同的删除记录)扫描/过滤方法。。查看查询中将在何处使用EXISTS()?抱歉,但是有成千上万的记录,我不能为所有这些创建声明,而且是由于大量记录的性质导致了速度的缓慢。这是一个评论,而不是一个答案。你应该在询问更多细节时使用评论。我无法作为新的投稿人添加评论
SELECT DISTINCT skt.VCDRAWING_REG_NO, skb.NDRAWING_ORG_NO, skb.NDRAWING_ORG_REV_NO, skb.CAPPLY_START_DATE, skb.CAPPLY_END_DATE, skto.*
FROM SPM_ABS_TRANBASE skt
JOIN SPM_ABS_BASE skb
ON skt.NDRAWING_ORG_REV_NO = skb.NDRAWING_ORG_REV_NO
AND skt.NDRAWING_ORG_NO = skb.NDRAWING_ORG_NO
JOIN SPM_ABS_MODEL skm
ON skb.NDRAWING_ORG_REV_NO = skm.NDRAWING_ORG_REV_NO
AND skb.NDRAWING_ORG_NO = skm.NDRAWING_ORG_NO
JOIN SPM_ABS_TRANOPT skto
ON skt.NDRAWING_SYSTEM_NO = skto.NDRAWING_SYSTEM_NO
JOIN ModelImport mi
ON skm.CMODEL = mi.ModelCode
WHERE (skb.CAPPLY_START_DATE <= DATEADD(day, 2, GETDATE()) OR skb.CAPPLY_START_DATE IS NULL)
AND (skb.CAPPLY_END_DATE >= DATEADD(day, -2, GETDATE()) OR skb.CAPPLY_END_DATE IS NULL)
AND mi.ModelCode = '3FBK5'
SELECT  skt.VCDRAWING_REG_NO, 
        skb.NDRAWING_ORG_NO, 
        skb.NDRAWING_ORG_REV_NO, 
        skb.CAPPLY_START_DATE, 
        skb.CAPPLY_END_DATE, 
        skto.NDRAWING_SYSTEM_NO
FROM    SPM_ABS_TRANBASE skt
        JOIN SPM_ABS_BASE skb ON 
            skt.NDRAWING_ORG_REV_NO = skb.NDRAWING_ORG_REV_NO
            AND skt.NDRAWING_ORG_NO = skb.NDRAWING_ORG_NO
        JOIN SPM_ABS_MODEL skm ON 
            skb.NDRAWING_ORG_REV_NO = skm.NDRAWING_ORG_REV_NO
            AND skb.NDRAWING_ORG_NO = skm.NDRAWING_ORG_NO
        JOIN SPM_ABS_TRANOPT skto ON 
            skt.NDRAWING_SYSTEM_NO = skto.NDRAWING_SYSTEM_NO
        JOIN ModelImport mi ON 
            skm.CMODEL = mi.ModelCode
WHERE   ISNULL(skb.CAPPLY_START_DATE, DATEADD(day, 2, GETDATE())) <= DATEADD(day, 2, GETDATE())
        AND ISNULL(skb.CAPPLY_END_DATE,DATEADD(day, -2, GETDATE())) >= DATEADD(day, -2, GETDATE())
GROUP BY skt.VCDRAWING_REG_NO, 
        skb.NDRAWING_ORG_NO, 
        skb.NDRAWING_ORG_REV_NO, 
        skb.CAPPLY_START_DATE, 
        skb.CAPPLY_END_DATE,
        skto.NDRAWING_SYSTEM_NO