2011-09-27 72 views
0

下面有一个简单的SQL语句JOIN为什么这个SQL查询需要8个小时才能完成?

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个reccords和表TB_INVENTORY有7688.不过,最后两个表(TB_NODETB_PROCESS)都少于30个记录。令人难以置信的是,它在SQL Server 2005中运行时,需要8小时才能返回结果集。

为什么需要很长时间来执行?

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

这是怎么回事?

有至少两个UNIQUE NONCLUSTERED INDEX es。

一个是IX_INVENTORY_BARCODE_PROCESS_NODE在桌子上TB_R_INVENTORY_BARCODE,其覆盖四列(inventidbarcodeprocess,和node)。

另一种是IX_BARCODE_PROCESS_NODE在桌子上tbBCScanRec,它覆盖三列(BarCodePASSEDPROCESS,和PASSEDNODE)。

+4

我不能推荐任何具体的教程,但你需要学习理解执行计划。在SSMS中有一些选项可以打开执行计划 - 如果你可以补充一下,我们可能会给你一些指示(尽管发布一个XML查询计划,尽管如此)。此外,通常使用实际值而不是预计值计划更好,但如果预计需要8小时才能获得实际值,则预计计划可能已足够。 –

回答

2

好了,标准答案,这样的问题:

  1. 确保您拥有所有必要的指标来代替,即指标上N.NO_IDREC.PASSEDNODEP.PR_CODEREC.PASSEDPROCESS
  2. 确保类型你加入的列是相同的,所以不需要隐式转换。
+0

有至少TOW独特的非结论性指数 – WangHu

+0

感谢您的建议.. – WangHu

1

您正在使用(556553 * 30 * 30)500百万行左右。 您可能必须在桌上添加indexes

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

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

+0

我不按照您估计的5亿行。你可以解释吗? –

+0

加工过程中处理**的估计最大行数**是笛卡尔乘积。这是每个表格行数的乘积:“最差”情况... –

+0

好吧,那么是不是在谈论结果集的大小?那么你在计算中错过了两张表,不是吗? 'TB_R_INVENTORY_BARCODE'具有260513行和'TB_INVENTORY'具有7688行 –

相关问题