为什么这个SQL查询需要8个小时才能完成?

时间:2011-09-27 07:18:06

标签: sql

下面有一个简单的SQL JOIN语句:

SELECT     
    REC.[BarCode]
   ,REC.[PASSEDPROCESS]
   ,REC.[PASSEDNODE]
   ,REC.[ENABLE]
   ,REC.[ScanTime]
   ,REC.[ID]
   ,REC.[Se_Scanner]
   ,REC.[UserCode]
   ,REC.[aufnr]
   ,REC.[dispatcher]
   ,REC.[matnr]
   ,REC.[unitcount]
   ,REC.[maktx]
   ,REC.[color]
   ,REC.[machinecode]
   ,P.PR_NAME
   ,N.NO_NAME
   ,I.[inventoryID]
   ,I.[status]
   FROM  tbBCScanRec as REC  
       left join TB_R_INVENTORY_BARCODE as R 
         ON    REC.[BarCode] = R.[barcode] 
           AND REC.[PASSEDPROCESS] = R.[process]
           AND REC.[PASSEDNODE] = R.[node]
       left join TB_INVENTORY  as I 
         ON R.[inventid] = I.[id]
       INNER JOIN  TB_NODE as N 
         ON N.NO_ID  =  REC.PASSEDNODE
       INNER JOIN  TB_PROCESS  as P 
         ON P.PR_CODE    = REC.PASSEDPROCESS

tbBCScanRec有556553条记录,而表TB_R_INVENTORY_BARCODE有260513条记录,而表TB_INVENTORY有7688条。但是,最后两个表(TB_NODE和{{ 1}})两个记录都少于30个。

令人难以置信的是,当它在SQL Server 2005中运行时,返回结果集需要8个小时。

为什么要花这么多时间执行?

如果删除了两个TB_PROCESS,则只需十秒钟即可完成运行。

怎么回事?

至少有两个inner join es。

UNIQUE NONCLUSTERED INDEX上有一个IX_INVENTORY_BARCODE_PROCESS_NODE,其中包含四列(TB_R_INVENTORY_BARCODEinventidbarcodeprocess)。

另一个是node,其中包含三列(IX_BARCODE_PROCESS_NODEtbBCScanRecBarCode)。

3 个答案:

答案 0 :(得分:2)

嗯,这样的问题的标准答案:

  1. 确保您拥有所有必要的索引,即N.NO_IDREC.PASSEDNODEP.PR_CODEREC.PASSEDPROCESS
  2. 上的索引
  3. 确保您加入的列的类型相同,因此不需要进行隐式转换。

答案 1 :(得分:1)

您正在使用(556553 * 30 * 30)5亿行。 您可能需要在表格中添加indexes

如果您使用的是SQL Server,则可以查看计划查询以查看失去时间的位置。 请参阅此处的文档:http://msdn.microsoft.com/en-us/library/ms190623(v=sql.90).aspx

查询计划将帮助您创建索引。

答案 2 :(得分:0)

检查索引时,也应该有聚簇索引 - 非聚簇索引使用聚簇索引,因此没有聚簇索引会使非聚簇索引无用。过时的统计数据也可能是一个问题。

但是,为什么需要获取所有数据?那是什么意思?您应该将WHERE子句限制为仅将结果集限制为您需要的内容。