2013-06-26 12 views
0

我正在使用查詢連接列,其中一個具有聚簇索引,另一個具有非聚簇索引。查詢花費很長時間。這是我使用不同類型的索引的原因嗎?在具有不同索引的列上加入

SELECT @NoOfOldBills = COUNT(*) 
FROM Billing_Detail D, Meter_Info m, Meter_Reading mr 
WHERE D.Meter_Reading_ID = mr.id 
    AND m.id = mr.Meter_Info_ID 
    AND m.id = @Meter_Info_ID 
    AND BillType = 'Meter' 

IF (@NoOfOldBills > 0) BEGIN 

    SELECT TOP 1 @PReadingDate = Bill_Date 
    FROM Billing_Detail D, Meter_Info m, Meter_Reading mr 
    WHERE D.Meter_Reading_ID = mr.id 
      AND m.id = mr.Meter_Info_ID 
      AND m.id = @Meter_Info_ID 
      AND billtype = 'Meter' 
    ORDER BY Bill_Date DESC 

END 
+4

表中有多少行?有多少個索引?執行計劃說什麼?你的SQL代碼在哪裏? –

+0

兩個表中均爲150 k。 實際上查詢太大,但執行計劃說這個查詢佔用33%,類似於這個查詢也需要33%,如果我得到這個解決方案,那麼我可以改善時間。 – Mustafa

+0

選擇@NoOfOldBills = COUNT(*) \t \t \t \t \t \t \t從Billing_Detail d,Meter_Info米,Meter_Reading先生 \t \t \t \t \t \t \t其中d.Meter_Reading_ID = mr.ID和m.Id = mr.Meter_Info_ID和m。ID = @ Meter_Info_ID AND BillType = '儀表' \t \t \t \t \t \t \t \t \t \t IF(@NoOfOldBills> 0) \t \t \t \t \t \t \t BEGIN \t \t \t \t \t \t \t \t選擇頂部1 @ PReadingDate = Bill_Date \t \t \t \t \t \t \t \t從Billing_Detail d,Meter_Info米,Meter_Reading先生 \t \t \t \t \t \t \t \t其中d.Meter_Reading_ID = mr.ID和m.Id = mr.Meter_Info_ID和[email protected]_Info_ID和billtype = '表' ORDER BY Bill_Date遞減\t \t \t \t \t \t \t END – Mustafa

回答

0

確定這裏有很多東西。首先,你是否有相關的指標(或儘可能相關)。每個表上應該有一個聚簇索引 - 如果該表沒有非聚簇索引用於標識行的聚簇索引,則非聚簇索引無法有效工作。

您的索引是否只包含一列? SQL Server使用索引,該索引的列順序非常重要。索引最左邊的列應該(一般來說)是具有最大規模的列(將數據劃分爲最小數量)索引中的任何一個都覆蓋查詢中引用的所有列(這被稱爲覆蓋索引(谷歌此更多信息)

一般來說索引應該是寬的,如果SQL Server有一個索引col1,col2,col3,col4和另一個col1,col2後面是多餘的,作爲來自第二個索引完全包含在第一個中,SQL Server理解這一點。

您是否統計數據是最新的?如果統計數據不是最新的,SQL Server可以/將選擇一個錯誤的執行計劃。計劃執行(SSMS查詢|顯示執行計劃)?

+0

數據庫表中的每個主鍵都有一個集羣索引,而外鍵有非集羣索引。而且我只在一列上創建了索引,我應該覆蓋所有列嗎? – Mustafa

+0

是按需添加覆蓋指數或確實覆蓋指數,以確保覆蓋每個連接的每一半。實際上,SSMS將在分析查詢時推薦您需要的索引,過去這種情況過去非常糟糕,但在最近的版本中有所改進。但明智地使用它的指導。 –

1

不知道更多的細節和上下文,建議很棘手 - 但它看起來像你試圖找出最古老的賬單的日期。您可能可以將這兩個查詢重寫爲一個,這會顯着提高性能(假設有一些舊賬單)。

我會建議這樣的事情 - 除了可能表現更好,還有點容易閱讀!

SELECT count(d.*) NoOfOldBills, MAX(d.Billing_Date) OldestBillingDate FROM Billing_Detail d 
    INNER JOIN Meter_Reading mr ON mr.id=d.Meter_Reading_ID 
    INNER JOIN Meter_Info m ON m.Id=mr.Meter_Info_ID 
WHERE 
    m.id = @Meter_Info_ID AND billtype = 'Meter' 
0

原因並非因爲您有不同類型的指數。既然你說過你在所有主鍵上都有索引,那你應該沒問題。爲了支持這個查詢,你還需要在BillType和Bill_Date上有兩列的索引來縮短時間。

希望他們在同一張桌子上。否則,您可能需要一些索引來最終創建一個具有兩列的索引。

相關問題