帮助重构 SQL 查询

发布于 2024-07-27 05:10:52 字数 2769 浏览 5 评论 0原文

下面是我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清浅ˋ旧时光 2024-08-03 05:10:52

很难说是什么原因造成的,但以下可能会造成影响:

  • 对连接中的值执行 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.

挽清梦 2024-08-03 05:10:52

您可以做的是在执行此查询时使用 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.

给我一枪 2024-08-03 05:10:52

另一件事 - 您可以尝试将一些条件从 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 

但我认为查询优化器应该这样做。

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

And another thing - you can try to place some conditions from WHERE into JOIN:

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

but I think Query Optimizer should do it.

anyway, you need to view execution plan first.

划一舟意中人 2024-08-03 05:10:52

执行计划会准确地告诉您什么花费了最多的时间。

这可能是导致最多工作的最后一个连接。 当您比较计算值时,数据库无法使用索引进行查找。

我看到您对数值执行了 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 to PrefixNo, then you are comparing a bit more of the field to PrefixNo + 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文