2013-05-30 152 views
1

我有一個用MS SQL Server R2編寫的查詢。請幫助優化它。它返回超過6個Lakhs的字符串數據結構。返回結果大約需要5-6分鐘。有什麼辦法可以改善嗎?優化SQL查詢以減少執行時間

下面是我的查詢:

CREATE proc [dbo].[Test] 
( 
@UserTypeID int,  
@UserID int,  
@CityID int,  
@OperatorID int,  
@ParameterID int  
)     
as  
begin  
declare @temp table  
( 
range decimal(18,2),  
range2 decimal(18,2),  
image varchar(50),  
symbol varchar(20)  
)  
If(@UserID>0)   
Begin  
--print 'hii'  
Insert into @temp(range,range2,image,symbol)   
SELECT  tbl_Legend_ViewNetwork_Dtls.range, tbl_Legend_ViewNetwork_Dtls.range2, tbl_Legend_ViewNetwork_Dtls.image,tbl_Legend_ViewNetwork_Dtls.symbol   
FROM   tbl_Legend_ViewNetwork_Dtls INNER JOIN   
         tbl_Legend_ViewNetwork ON tbl_Legend_ViewNetwork_Dtls.tbl_legend_view_network_id = tbl_Legend_ViewNetwork.id   
WHERE tbl_Legend_ViewNetwork.parameter_id = @ParameterID and tbl_Legend_ViewNetwork.user_type_id = @UserTypeID and tbl_Legend_ViewNetwork.is_default = 1 and tbl_Legend_ViewNetwork.user_id = @UserID   

update @temp set  
range = range2,  
range2 = range  
where symbol = '<'  
End   
Else   
Begin   
Insert into @temp(range,range2,image,symbol)   
SELECT  tbl_Legend_ViewNetwork_Dtls.range, tbl_Legend_ViewNetwork_Dtls.range2, tbl_Legend_ViewNetwork_Dtls.image,tbl_Legend_ViewNetwork_Dtls.symbol   
FROM   tbl_Legend_ViewNetwork_Dtls INNER JOIN   
         tbl_Legend_ViewNetwork ON tbl_Legend_ViewNetwork_Dtls.tbl_legend_view_network_id = tbl_Legend_ViewNetwork.id   
WHERE tbl_Legend_ViewNetwork.parameter_id = @ParameterID and tbl_Legend_ViewNetwork.user_type_id = @UserTypeID and tbl_Legend_ViewNetwork.is_default = 1   

update @temp set  
range = range2,  
range2 = range  
where symbol = '<'  
End   
--select * from @temp   

Select '[' + STUFF(   
(SELECT ',{"latitude":"'+ a.lat+ '","longitude":"' + a.long+ '","value":"' +convert(varchar(20),a.value)+ '","image":"' +temp.image +'"}'  
FROM   (SELECT  tbl_Survey_Details.lat, tbl_Survey_Details.long, tbl_Survey_Details.value   
     FROM   tbl_Survey_Details INNER JOIN   
       tbl_Survey ON tbl_Survey_Details.tbl_survey_id = tbl_Survey.id INNER JOIN   
       tbl_Location ON tbl_Survey.tbl_location_id = tbl_Location.id INNER JOIN   
       tbl_Area ON tbl_Location.tbl_area_id = tbl_Area.id INNER JOIN  
       tbl_City ON tbl_Area.tbl_city_id = tbl_City.id  
WHERE tbl_Survey_Details.tbl_parameter_id = @ParameterID and tbl_Survey.tbl_mobile_operator_id = @OperatorID and tbl_Area.tbl_city_id = @CityID) AS a  
INNER JOIN @temp temp on a.value between temp.range and temp.range2  
For XML Path ('')),1,1,'') + ']' as data  
End 

回答

0

如果您在MS SQL Management Studio中的查詢分析器此查詢並單擊菜單查詢,分析數據庫引擎優化顧問這個查詢它會告訴你啥子,你需要索引加上優化查詢...

PS爲我們這些外來南亞萬盧比爲100,000

+0

我試了一下,它給了我一些建議(在survey_details表索引),我應用了所有,我只有幾秒的差異。其他可能的解決方案? –

+0

大部分時間花在哪裏?如果數據發生很大變化,那麼通常需要很長時間。你真的想要一次定位1-10 000行,所以使用你增量的變量來分割範圍。我不知道是否最好在用戶ID或範圍上分割,攻擊查詢分析器中佔據最大比例的位。 –

+0

已轉移到[此鏈接](http://dba.stackexchange.com/questions/43553/reduce-clustered-index-seek-cost-sql-server-2008-r2) –

1

嘗試這一個 -

CREATE PROC [dbo].[Test] 
(
    @UserTypeID INT, 
    @UserID INT, 
    @CityID INT, 
    @OperatorID INT, 
    @ParameterID INT 
) 
AS BEGIN 

    SELECT data = '[' + STUFF((
     SELECT 
      ',{"latitude":"' + A.lat + '","longitude":"' + A.long + '","value":"' + CONVERT(VARCHAR(20), A.value) + '","image":"' + temp.IMAGE + '"}' 
     FROM (
      SELECT 
        sd.lat 
       , sd.long 
       , sd.value 
      FROM dbo.tbl_Survey_Details sd 
      JOIN dbo.tbl_Survey s ON sd.tbl_survey_id = s.id 
      JOIN dbo.tbl_Location l ON s.tbl_location_id = l.id 
      JOIN dbo.tbl_Area a ON l.tbl_area_id = a.id 
      JOIN dbo.tbl_City c ON a.tbl_city_id = c.id 
      WHERE sd.tbl_parameter_id = @ParameterID 
       AND s.tbl_mobile_operator_id = @OperatorID 
       AND a.tbl_city_id = @CityID 
     ) a 
     JOIN (
      SELECT 
        [range] = CASE WHEN symbol = '<' THEN t.range2 ELSE t.[range] END 
       , range2 = CASE WHEN symbol = '<' THEN t.[range] ELSE t.range2 END 
       , [image] = t.[image] 
      FROM dbo.tbl_Legend_ViewNetwork_Dtls t 
      JOIN dbo.tbl_Legend_ViewNetwork n ON t.tbl_legend_view_network_id = n.id 
      WHERE n.parameter_id = @ParameterID 
       AND n.user_type_id = @UserTypeID 
       AND n.is_default = 1 
       AND (
         (
           n.[user_id] = @UserID 
          AND 
           @UserID > 0 
         ) 
         OR 
          @UserID <= 0 
       ) 
     ) temp ON A.value BETWEEN temp.[range] AND temp.range2 
     FOR XML PATH ('') 
    ), 1, 1, '') + ']' 

END 
+1

對不起,這一個需要更多的時間與我發佈的相比。 :( 什麼可以通過其他方式儘快獲得回覆。 –

+0

分區表會創造什麼好的影響嗎? –