帮助重构SQL查询

时间:2009-07-15 08:05:30

标签: sql sql-server sql-server-2000

下面是我的SQL查询,它需要超过10分钟且仍在运行....

select DISTINCT Auditdata.ID,ns.ProviderMaster_ID as CDRComment 
from Auditdata AuditData 
inner join AuditMaster am 
    on am.ID=AuditData.AuditMaster_ID 
inner join HomeCircleMaster hcm 
    on hcm.Ori_CircleMaster_ID=am.CircleMaster_ID 
    and hcm.Ori_ServiceTypeMaster_ID=1 
    and hcm.Dest_ServiceTypeMaster_ID=1 
inner join NoSeriesMaster ns 
    on (ns.CircleMaster_ID=am.CircleMaster_ID 
    or ns.CircleMaster_ID=hcm.Dest_CircleMaster_ID) 
    and ns.ProviderMaster_ID<>am.ProviderMaster_ID  
    and ns.ServiceTypeMaster_ID=1 
INNER JOIN    NoSeriesMaster_Prefix PD 
    ON SUBSTRING(AuditData.CallTo, 1, CONVERT(INT, PD.PrefixLen)) = PD.PrefixNo       
    AND LEN(AuditData.CallTo) = CONVERT(VARCHAR(10), CONVERT(INT, PD.PrefixLen) + CONVERT(INT, PD.AfterPrefixLen))  
    AND PD.PrefixNo + ns.NoSeries = LEFT(AuditData.CallTo, len(ns.NoSeries) + CONVERT(INT, PD.PrefixLen))  
 where  AuditData.TATCallType is null   
    and  AuditData.AuditMaster_ID=74 
    and PrefixType='CALL'

内连接中使用的evey列违反了索引,而where子句中使用的列也定义为索引...

有没有办法快速查询

请帮帮我......

感谢名单


亲爱的朋友我修改了我的SQL查询,因为它仍然需要花费大量时间来执行15000000

修改后的SQL Query如下:

select DISTINCT Auditdata.ID,ns.ProviderMaster_ID as CDRComment from Auditdata AuditData inner join AuditMaster am on am.ID=AuditData.AuditMaster_ID inner join HomeCircleMaster hcm on hcm.Ori_CircleMaster_ID=am.CircleMaster_ID and hcm.Ori_ServiceTypeMaster_ID=1 and hcm.Dest_ServiceTypeMaster_ID=1 inner join NoSeriesMaster ns on (ns.CircleMaster_ID=am.CircleMaster_ID or ns.CircleMaster_ID=hcm.Dest_CircleMaster_ID) and ns.ProviderMaster_ID<>am.ProviderMaster_ID and ns.ServiceTypeMaster_ID=1 INNER JOIN NoSeriesMaster_Prefix PD ON Auditdata.callto like PD.PrefixNo + '%' AND AuditData.CallTolen = PD.PrefixLen + PD.AfterPrefixLen AND PD.PrefixNo + ns.NoSeries = LEFT(AuditData.CallTo, NoSeriesLen + PD.PrefixLen)
where AuditData.TATCallType is null and AuditData.AuditMaster_ID=74 and PrefixType='CALL' 

现在该怎么办?

亲爱的朋友

我的查询需要花费很多时间,因为 下面是部分代码  NoSeriesMaster包含4000行和Auditdata 15000000行 使用内连接每个callto列记录在与Noseriesmaster

匹配的auditdata中
  

INNER JOIN NoSeriesMaster_Prefix PD
         ON SUBSTRING(AuditData.CallTo,1,CONVERT(INT,PD.PrefixLen))= PD.PrefixNo
          AND LEN(AuditData.CallTo)= CONVERT(VARCHAR(10),CONVERT(INT,PD.PrefixLen)+ CONVERT(INT,PD.AfterPrefixLen))
          AND PD.PrefixNo + ns.NoSeries = LEFT(AuditData.CallTo,len(ns.NoSeries)+ CONVERT(INT,PD.PrefixLen))
  其中AuditData.TATCallType为null且AuditData.AuditMaster_ID = 74且PrefixType ='CALL'

4 个答案:

答案 0 :(得分:3)

很难说是什么导致了它,但以下内容可能有所贡献:

  • 对连接中的值执行SUBSTRING,CONVERT,LEFT等转换会破坏性能,因为这意味着SQL Server无法有效地使用其索引。您可能希望查看将进行此类转换所需的列提取到单独的列中并对其进行索引。

  • 次优索引 - 除了由于所有转换而无法使用的索引之外,您加入的其他列是否正确编入索引?看看索引调整向导,它可以帮助你。

答案 1 :(得分:2)

执行此查询时,您可以使用SQL Server Management Studio中的“执行计划”视图。 它将向您显示SQL花费最多时间处理查询的步骤。 从那里你至少知道需要进行优化的地方。

执行计划也在SQL Server Management Studio Express中有特色。

只需打开一个新的查询窗口,点击查询&gt;显示估计执行计划并运行查询。查询完成后,将弹出执行计划。

答案 2 :(得分:0)

另一件事 - 你可以尝试将一些条件从WHERE放入JOIN:

from Auditdata AuditData 
inner join AuditMaster am 
    on am.ID=AuditData.AuditMaster_ID AND AuditData.TATCallType is null   
    and  AuditData.AuditMaster_ID=74 

但我认为Query Optimizer应该这样做。

无论如何,您需要先查看执行计划。

答案 3 :(得分:0)

执行计划会告诉你到底花了多少时间。

这可能是造成最多工作的最后一次加入。在比较计算值时,数据库无法使用索引进行查找。

我看到你对数字值进行了CONVERT(VARCHAR(10), ...),然后将其与数字进行比较。您应该可以删除该转换。

您将字段PrefixLen转换为多个地方的数字。该字段是否为文本字段,如果是,是否可以将其转换为数字字段?

您正在将AuditData的第一部分与PrefixNo进行比较,然后您将该字段的更多位置与PrefixNo + NoSeries进行比较。除非由于缺少分隔符(例如'01'+'23'='0'+'123')而导致值“流血”,否则您可以删除第一个比较。