我有一个查询,它需要大约1分40秒来提供输出,有时需要超过2或3分钟。任何人都可以帮助并告诉我为什么花了这么多时间?输出结果大约为409799行。
Select
Distinct
A.ID
,tracactionId Contracid
,Cancaldate
,Suppliers
,Ct.Type "Contract Type"
,Sitename "Site Name"
,St.Telephone "Site Telephone"
,Cc.Mobile
,At.Type "Action Type"
,Ms.Status "Order Status"
,Name Client
,Ass.Status
,Isnull(
Case When Try_Parse(orderac As Numeric(10,2)) <= '60000' Then 'T3'
When Try_Parse(orderac As Numeric(10,2)) >= '60001' And
Try_Parse(orderac As Numeric(10,2)) <= '1000000' Then 'T2'
When Try_Parse(orderac As Numeric(10,2)) >= '1000001' Then 'T1' End,
'-') "Consumption Order"
,Isnull(
Case When Try_Parse(Replaceaq As Numeric(10,2)) <= '60000' Then 'T3'
When Try_Parse(Replaceaq As Numeric(10,2)) >= '60001' And
Try_Parse(Replaceaq As Numeric(10,2)) <= '1000000' Then 'T2'
When Try_Parse(Replaceaq As Numeric(10,2)) >= '1000001' Then 'T1' End,
'-') "Consumption Replace"
,Case When Datepart(Day, Cancaldate ) > 21 And Cancaldate < '9999-12-01'
Then Substring(Datename(Month, Dateadd(Month, 1, Cancaldate )), 1, 3) + '
' + Datename(Year, Dateadd(Month, 1, Cancaldate ))
Else Substring(Datename(Month, Cancaldate ), 1, 3) + ' ' + Datename(Year,
Cancaldate ) End As "Month Year"
From return A
Left Hash Join Contract C On C.Contractid = A.contractid
And orderdate In (Select
Max(Aa.orderdate) From Return Aa Where Aa.Contractid = A.Contractid)
Left Hash Join Suppliers S On S.Suppliersid = C.Supplierid
Left Hash Join ordercontract Mc On Mc.Contractid = C.Contractid
Left Hash Join order M On M.orderid = Mc.orderid
Left Hash Join Contracttype Ct On C.Contracttypeid= Ct.ordercontracttypeid
Left Hash Join Site St On St.Siteid = C.Siteid
Inner Hash Join ordersubtype Ast On Ast.ordersubtypeid = A.Aordersubtypeid
Inner Hash Join ordertype At On At.ordertypeid = A.ordertypeid
Left Hash Join oderstatus Ms On Ms.orderstatusid = M.orderstatusid
Inner Hash Join Users U On U.Userid = A.userid
Inner Hash Join orderstatus Ass On Ass.orderstatusid = A.orderstatusid
Inner Hash Join product On A.productid = product.productid
Inner Hash Join Contact Cc On product.Maincontactid = Cc.Contactid
where M.Meterstatusid <> 8
这是执行计划及其建议创建非聚集索引。
我是新手;请帮帮我。
/*
Missing Index Details from SQLQuery2.sql - 10.0.1.9.EnergyCRM_Main
(adminlocal (84))
The Query Processor estimates that implementing the following index could
improve the query cost by 15.558%.
*/
/*
USE [SAmpler]
GO
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[Action] ([orderID])
INCLUDE ([orderTypeID],[orderStatusID],[productID],[orderDate],
[AssignedToUserID],[orderSubTypeID])
GO
*/
答案 0 :(得分:3)
如果没有执行计划,这个问题很难回答。 看看代码我怀疑了几件事情;
ISNULL在索引列上使用时通常会损害性能,因为它禁止使用所述索引
为什么所有连接都指定为散列连接?在大多数情况下,最好让查询优化器决定哪个连接最快。
我看到很多try_parse,可能需要事先检查/处理列并将它们设置为所需的数据类型。在这种情况下,如果它是正确的数据类型,则不必检查每个列。
答案 1 :(得分:0)
这只是猜测,因为我们无法执行实际查询。我最好的猜测是你所有的ISNULL都在损害性能。
试试这个:
Case When Try_Parse(orderac As Numeric(10,2)) <= '60000' Then 'T3'
When Try_Parse(orderac As Numeric(10,2)) >= '60001' And
Try_Parse(orderac As Numeric(10,2)) <= '1000000' Then 'T2'
When Try_Parse(orderac As Numeric(10,2)) >= '1000001' Then 'T1'
ELSE '-' End AS "Consumption Order"
答案 2 :(得分:0)
只是弄清楚这个烂摊子
您需要指明列来自哪些表 不清楚所有表格都被使用
所有Try_Parse都是个问题
表连接提示应该是最后的手段
Select Distinct
A.ID
, tracactionId Contracid
, Cancaldate
, Suppliers
, Ct.Type "Contract Type"
, Sitename "Site Name"
, St.Telephone "Site Telephone"
, Cc.Mobile
, At.Type "Action Type"
, Ms.Status "Order Status"
, Name Client
, Ass.Status
, Isnull( Case When Try_Parse(orderac As Numeric(10,2)) <= '60000' Then 'T3'
When Try_Parse(orderac As Numeric(10,2)) >= '60001'
And Try_Parse(orderac As Numeric(10,2)) <= '1000000' Then 'T2'
When Try_Parse(orderac As Numeric(10,2)) >= '1000001' Then 'T1'
End
, '-'
) "Consumption Order"
, Isnull( Case When Try_Parse(Replaceaq As Numeric(10,2)) <= '60000' Then 'T3'
When Try_Parse(Replaceaq As Numeric(10,2)) >= '60001'
And Try_Parse(Replaceaq As Numeric(10,2)) <= '1000000' Then 'T2'
When Try_Parse(Replaceaq As Numeric(10,2)) >= '1000001' Then 'T1'
End
, '-'
) "Consumption Replace"
, Case When Datepart(Day, Cancaldate ) > 21 And Cancaldate < '9999-12-01'
Then Substring(Datename(Month, Dateadd(Month, 1, Cancaldate )), 1, 3)
+ ' ' + Datename(Year, Dateadd(Month, 1, Cancaldate ))
Else Substring(Datename(Month, Cancaldate ), 1, 3)
+ ' ' + Datename(Year, Cancaldate )
End As "Month Year"
From return A
Inner Hash Join ordersubtype Ast On Ast.ordersubtypeid = A.Aordersubtypeid
Inner Hash Join ordertype At On At.ordertypeid = A.ordertypeid
Inner Hash Join orderstatus Ass On Ass.orderstatusid = A.orderstatusid
Inner Hash Join Users U On U.Userid = A.userid
Inner Hash Join product On product.productid = A.productid
Inner Hash Join Contact Cc On Cc.Contactid = product.Maincontactid
Left Hash Join Contract C
On C.Contractid = A.contractid
And orderdate In ( Select Max(Aa.orderdate)
From Return Aa
Where Aa.Contractid = A.Contractid
)
Left Hash Join Suppliers S On S.Suppliersid = C.Supplierid
Left Hash Join Contracttype Ct On Ct.ordercontracttypeid = C.Contracttypeid
Left Hash Join Site St On St.Siteid = C.Siteid
Left Hash Join ordercontract Mc On Mc.Contractid = C.Contractid
Left Hash Join order M On M.orderid = Mc.orderid
Left Hash Join oderstatus Ms On Ms.orderstatusid = M.orderstatusid
where M.Meterstatusid <> 8