2010-11-02 42 views
4

好吧,在我開始之前我想說,我對這個Sql索引來說是全新的東西。在沒有連接和可預測查詢的表上進行Sql Server索引

我有一個不加入任何東西的表格。它有以下列:

Id (int) 
String1 (nvarchar(10) 
String2 (nvarchar(50) 
DateTime1 (date) 
DateTime2 (date) 
DateTime3 (date) 

我在該表上有大約100,000,000行。搜索它很慢,所以我想我必須添加一些索引。

我將只運行以下查詢:

查詢1

select * from Table 
where String1 = "Blah" and 
String 2 = "Blah" and 
DateTime1 <= {someTime1} and 
DateTime2 >= {someTime1} 

查詢2

select * from Table 
where String1 = "Blah" and 
String 2 = "Blah" and 
DateTime2 >= {someTime1} 

查詢3

select * from Table 
where String1 = "Blah" and 
String 2 = "Blah" and 
DateTime3 >= {someTime1} 

請注意,他們幾乎是相同的查詢,除了他們有一個稍微不同的日期比較。另外,排序不是問題。

所以我嘗試在列String1,String2,DateTime1,DateTime2上添加一個非聚集索引。運行查詢1這裏是我所看到的:

  1. 它是快了很多了,但是仍然需要大約20秒加載。
  2. 我注意到,對於相同的完全相同的查詢(具有相同的搜索參數),如果我再次調用它,它將在不到一秒鐘內返回數據。
  3. 我注意到,如果我運行查詢1與其他一些參數,它將再次需要20秒加載。
  4. 我注意到我的RAM上升並在查詢後保持。

因此,這裏是我的問題:

  1. 我這樣做對嗎?爲什麼需要20秒才能加載?添加索引後不應該很快嗎?
  2. 什麼是Sql服務器與我的RAM?因爲我有一張大桌子,我需要更多的RAM嗎?
  3. 我是否需要爲查詢2和查詢3添加新的索引?或者是我添加的索引已經足夠用於其他2個查詢?

感謝,

+0

你知道,我讀過很多SQL的問題。這是一個很好的問題。榮譽。 – Matt 2010-11-02 22:22:35

回答

2
  1. 解析和編譯查詢,並可能從磁盤讀取。這就是它第二次快速運行的原因。當參數改變時需要花費時間再次編譯。

  2. 數據緩存。又名緩衝池。一般來說,更多的內存不會與SQL Server出錯。

  3. 查詢1和查詢2是相同的,查詢3是不同的。

我建議2個指標入手

  • 字符串1,字符串2,DATETIME2,DateTime1 INCLUDE DateTime3
  • 字符串1,字符串2,DateTime3 INCLUDE DATETIME2,DateTime1

其他想法關於數據類型...越小越好如果當然

編輯:

磁盤讀取將發生一個到內存(簡單),所以更多的內存將幫助 然而,我懷疑20 secodns是編譯+統計等,不從磁盤讀取

+0

謝謝gbn。我正在選擇大約2k行,並且磁盤讀取什麼花費了時間?有沒有關於如何使其更快的建議? – 2010-11-02 17:59:49

+0

還有一個問題,那麼有什麼方法可以減少編譯和統計時間?將這些存儲過程轉移到幫助中? – 2010-11-02 18:13:26

+0

@Chi Chan:可以。你更有可能獲得計劃重複使用比硬編碼參數 – gbn 2010-11-02 18:15:21

0

我建議你使用SQL Server的數據庫優化顧問(DTA)和Profiler熟悉自己。

這裏是一個很好的文章:

http://www.zimbio.com/SQL/articles/655/How+Tune+Database+Using+Database+Tuning+Advisor

DTA不會永遠給你最完美的建議,但它通常是一個良好的開端。如果您使用分析器,您可以監控數據庫一天,然後將其傳遞給DTA。

還有其他事情要考慮,如:

  • 特定查詢多久會被 運行
  • 多久將表已 記錄插入或更新

請記住,索引會減慢你的插入和更新。

要做的另一件重要的事情是確保從每個查詢運行的同一條基線開始。我懷疑你在問題中看到1和2的結果,因爲你已經緩存了數據。 Here is a good link,該如何測試sql腳本。

0

查詢1的問題是它有兩個獨立的範圍條件。最近有一個非常類似的問題。我解釋說,具體問題有:How Database stores data internally in B-Tree/B+Tree

關於查詢2

,如果你會使用以下指標:

String1, String2, Date2, Date 1 

它可以成爲QUERY2相當好,並且不改變QUERY1(除date1上的條件比date2更有選擇性)。

QUERY3可能需要額外的指標:

String1, String2, Date3 

不過,我不喜歡與相同前綴的兩個指標。我可能會轉向String1和String2 - 以防萬一某些查詢只有String2。


想更好地理解所有這些索引的東西嗎?看看我的free eBook "Use The Index, Luke"

0
  1. 我正在做對嗎?爲什麼需要20秒才能加載?添加索引後不應該很快嗎?

- >我認爲你做得很好,但我也會在你的查詢中看到數據選擇性。 您的典型查詢中有多少條記錄會返回100,000,000? 如果結果集很小(整個表的3〜5%),索引是很好的分辨率。

  1. 什麼是Sql server與我的RAM做什麼?因爲我有一張大桌子,我需要更多的RAM嗎? - > DBMS正在將數據(逐塊)從物理存儲移動到您的RAM以執行您的查詢。你的查詢也需要解析,它會消耗一些內存。
0

更多的內存將有所幫助,具體取決於您的操作系統安裝SQL Server時,SQL Server的版本以及您已擁有多少內存。它們在RAM上沒有相同的限制。

爲了將來的參考,請使用SQL Server Management Studio(SSMS)中數據庫優化顧問中的分析查詢。你現在可能不需要它,但是當表格變得更復雜時可以提供幫助。

你在這個表上有主鍵嗎?只是好奇,你從來沒有提到過它。

+0

Id是p.Key,但它是使用hi-lo與nhibernate分配的隨機int。可以肯定地說,我永遠不會使用密鑰來選擇/更新/刪除任何東西。 – 2010-11-02 18:09:56