帮助重构 SQL 查询
下面是我的 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'
内连接中使用的每个列都定义了索引,而 where 子句中使用的列也定义了索引...
有什么方法可以快速执行以上查询
吗?帮助我...
谢谢
亲爱的朋友们,我修改了我的 SQL 查询如下,它仍然需要很多时间来执行 针对 15000000 个
修改后的 SQL 查询如下:
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 行 通过内部联接,auditdata 中的每个 callto 列记录都与 Noseriesmaster 匹配
内连接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'
Below is my SQL Query which takes more than 10 minutes and still running....
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 column used in the inner join defied a index and columns used in where clause is also defined index...
is there any way to fast above query
Please help me...
Thanx
Dear Friends i m modified my SQL Query is as follow its still take lot of time to execute Against 15000000
modified SQL Query are as follows:
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'
Now what can i do??
Dear friend
my Query takes lot times because
below part of code
NoSeriesMaster Contain 4000 rows and Auditdata 15000000 rows
with inner join every callto columns record in auditdata matched with the Noseriesmaster
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'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
很难说是什么原因造成的,但以下可能会造成影响:
对连接中的值执行 SUBSTRING、CONVERT、LEFT 等转换会破坏性能,因为这意味着 SQL Server 无法有效地使用其索引。 您可能需要考虑将需要进行此类转换的列提取到单独的列中并为其建立索引。
次优索引 - 除了由于所有转换而无法使用的索引之外,您要加入的其他列是否已正确建立索引? 请查看索引调整向导,它可能会在这里为您提供帮助。
It's difficult to say what is causing it, but the following may contribute:
Performing transformations such as SUBSTRING, CONVERT, LEFT etc on values in joins will ruin performance, because it means SQL Server can't effectively use its indexes. You may want to look at extracting the columns you need to do this type of conversion on into separate columns and index them.
Sub-optimal indexes - apart from the ones you can't use due to all the conversions, are the other columns you're joining on correctly indexed? Take a look at the index tuning wizard which may be able to help you out here.
您可以做的是在执行此查询时使用 SQL Server Management Studio 内的执行计划视图。
它将显示 SQL 在处理查询时花费最多时间的步骤。
从那里您至少知道需要在哪里进行优化。
仅供参考,SQL Server Management Studio Express 中还提供了执行计划。
只需打开一个新的查询窗口,点击查询> 显示估计执行计划并运行您的查询。 查询完成后,将弹出执行计划。
What you can do is use the Execution Plan view inside SQL Server Management Studio when you execute this query.
It will show you on which steps SQL spends the most time to process your query.
From there you at least have an idea where the optimization needs to occur.
The Execution Plan is also featured in SQL Server Management Studio Express fyi.
Just open a new Query Window, click Query > Display Estimated Execution Plan and run your query. The execution plan will pop up once the query has completed.
另一件事 - 您可以尝试将一些条件从 WHERE 放入 JOIN:
但我认为查询优化器应该这样做。
无论如何,你需要先查看执行计划。
And another thing - you can try to place some conditions from WHERE into JOIN:
but I think Query Optimizer should do it.
anyway, you need to view execution plan first.
执行计划会准确地告诉您什么花费了最多的时间。
这可能是导致最多工作的最后一个连接。 当您比较计算值时,数据库无法使用索引进行查找。
我看到您对数值执行了
CONVERT(VARCHAR(10), ...)
,然后将其与数字进行比较。 您应该能够删除该转换。您在多个位置将字段
PrefixLen
转换为数字。 该字段真的是文本字段吗?如果是,您可以将其转换为数字字段吗?您将
AuditData
的第一部分与PrefixNo
进行比较,然后将该字段的更多部分与PrefixNo + NoSeries
进行比较。 除非由于缺少分隔符而导致值“出血”(例如“01”+“23”=“0”+“123”)出现问题,否则您可以删除第一个比较。The execution plan would tell you exactly what's taking the most time.
It's likely the last join that is causing the most work. As you are comparing calculated values, the database can't use indexes for lookup.
I see that you do a
CONVERT(VARCHAR(10), ...)
on a numeric value, but then you compare it to a number. You should be able to just remove that conversion.You convert the field
PrefixLen
to a number in several places. Is that field realy a text field, and if it is, can you convert it to a numerical field?You are comparing the first part of
AuditData
toPrefixNo
, then you are comparing a bit more of the field toPrefixNo + NoSeries
. Unless there is an issue with values "bleeding" because a lack of separator (e.g. '01'+'23' = '0'+'123') you could just remove the first comparison.