下面是我的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'
答案 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')而导致值“流血”,否则您可以删除第一个比较。