2014-11-17 70 views
0

我有一個預先寫好的SQL Query,它需要45 minutes實際運行並顯示數據。它返回總計80000+記錄。但需要很多時間來運行和顯示數據。舊的SQL查詢優化

SELECT 
hq.QuoteHeaderId, 
hq.HandsetQuoteId, 
hq.QuoteDate, 
t_PhoneAudit.PhoneModelId, 
t_PhoneAudit.IMEI, 
t_PhoneModel.ModelName, 
t_PhoneBrand.Name As BrandName 
, al.ActivityId 
, par.Result 
, al.CustomMessage, 
al.[Description] 
,thqai.Value AS AgentName 
FROM [t_DynaGroupMissingRecordsProcessing] 
INNER JOIN t_HandsetQuote hq ON t_DynaGroupMissingRecordsProcessing.HandsetQuoteId = hq.HandsetQuoteId 
INNER JOIN t_PhoneAudit ON t_PhoneAudit.PhoneAuditId = hq.QuotePhoneAuditId 
INNER JOIN t_PhoneModel ON t_PhoneModel.PhoneModelId = t_PhoneAudit.PhoneModelId 
INNER JOIN t_PhoneBrand ON t_PhoneBrand.PhoneBrandId = t_PhoneModel.PhoneBrandId 
INNER JOIN 
(
    SELECT par.HandsetQuoteId, txt_Value AS ActivityId, 'OK' AS Result FROM t_PhoneAuditRetail par CROSS APPLY dbo.fn_ParseText2Table(par.Ok, ',') 
    UNION 
    SELECT par.HandsetQuoteId, txt_Value AS ActivityId, 'Fault' AS Result FROM t_PhoneAuditRetail par CROSS APPLY dbo.fn_ParseText2Table(par.Fault, ',') 
) par ON hq.HandsetQuoteId = par.HandsetQuoteId 
INNER JOIN t_ActivityLocalization al ON par.ActivityId = al.ActivityId 
INNER JOIN t_ContactChannel CC ON al.ContactChannelId = CC.ContactChannelId 
INNER JOIN t_testingProfiledetails ON t_testingProfiledetails.ActivityId = al.ActivityId AND ( IsVisibleForRetail = '1' OR t_testingProfiledetails.ActivityId IN ('93','97')) AND t_testingProfiledetails.ProfileId IN (SELECT DefailtRetailProfileId FROM t_ContactChannel WHERE Name IN ('Holland Retail', 'BelCompanyNPEY Retail', 'Belcompany Retail', 'HollandNPEY Retail')) 
LEFT OUTER JOIN t_HandsetQuoteAdditionalInfo thqai on thqai.HandsetQuoteId = hq.HandsetQuoteId and thqai.KeyName = 'AgentName' 
WHERE [t_DynaGroupMissingRecordsProcessing].IsProcessed = 0 
AND CC.Name IN ('Holland Retail', 'BelCompanyNPEY Retail', 'Belcompany Retail', 'HollandNPEY Retail') 
ORDER BY hq.HandsetQuoteId 

主要問題是用CC.Name IN ('Holland Retail', 'BelCompanyNPEY Retail', 'Belcompany Retail', 'HollandNPEY Retail')這個說法。

如果我繼續在In Statement中添加名稱,查詢會變得越來越慢。

下面是我使用的功能把定義:

ALTER FUNCTION [dbo].[fn_ParseText2Table]  
( 
@p_SourceText VARCHAR(8000) 
,@p_Delimeter VARCHAR(100) = ',' --default to comma delimited.  
)  
RETURNS @retTable TABLE  
( 
txt_value VARCHAR(2000)  
)  
AS  
BEGIN  
DECLARE @w_Continue int  
,@w_StartPos int  
,@w_Length int  
,@w_Delimeter_pos int  
,@w_tmp_txt VARCHAR(2000)  
,@w_Delimeter_Len tinyint  

SET @w_Continue = 1  
SET @w_StartPos = 1  
SET @p_SourceText = RTRIM(LTRIM(@p_SourceText))  
SET @w_Length = DATALENGTH(RTRIM(LTRIM(@p_SourceText)))  
SET @w_Delimeter_Len = len(@p_Delimeter)  

WHILE @w_Continue = 1  
BEGIN  
SET @w_Delimeter_pos = CHARINDEX(@p_Delimeter,(SUBSTRING(@p_SourceText, @w_StartPos,((@w_Length - @w_StartPos)[email protected]_Delimeter_Len))))  
IF @w_Delimeter_pos > 0 -- delimeter(s) found, get the value  
BEGIN  
    SET @w_tmp_txt = LTRIM(RTRIM(SUBSTRING(@p_SourceText, @w_StartPos  
,(@w_Delimeter_pos - 1))))  
    SET @w_StartPos = @w_Delimeter_pos + @w_StartPos + (@w_Delimeter_Len- 1)  
END  
ELSE  -- No more delimeters, get last value  
BEGIN  
    SET @w_tmp_txt = LTRIM(RTRIM(SUBSTRING(@p_SourceText, @w_StartPos  
    ,((@w_Length - @w_StartPos) + @w_Delimeter_Len))))  
    SELECT @w_Continue = 0  
END  
INSERT INTO @retTable VALUES(@w_tmp_txt)  
END  
RETURN 

END

請幫我優化這個查詢。

+0

我會通過看你使用的功能開始。 – Chris

+0

@Chris請檢查更新後的問題 – HarshSharma

回答

0

你可以試試這個

Insert the list of names to @table(name) and join it to cc 
on [email protected] 
+0

謝謝!它運作良好 – HarshSharma

+0

你節省多少時間? –

+0

很好的時間,它現在運行在1分鐘:)榮譽!!! – HarshSharma