2013-07-11 163 views
1

我有70萬項與快速文本搜索表的數據庫。每一行都有與之關聯的時間。我需要一次有效地分頁記錄100行。我通過追蹤一天的結束來做到這一點。SQL查詢太慢

它走太長時間來執行(15秒)

下面是一個例子查詢:

SELECT * 
FROM Objects o, FTSObjects f 
WHERE f.rowid = o.AutoIncID AND 
    o.TimeStamp > '2012-07-11 14:24:16.582' AND 
    o.TimeStamp <= '2012-07-12 04:00:00.000' AND 
    o.Name='GPSHistory' 
ORDER BY o.TimeStamp 
LIMIT 100 

時間戳字段建立索引。

我想這是因爲Order By語句排序的所有返回的記錄,然後做一個限制,但我不知道。

對此提出建議?

+0

上'Timestamp'是我的建議索引。 – Matthew

+0

時間戳索引@Matthew –

+0

一個連接語法也可能在這裏幫助'JOIN FTSObjects f ON f.rowid = o.AutoIncID',但我認爲優化器已經爲你做了。 – Matthew

回答

2

最好的辦法是得到一個好的DBA來看看所產生的計劃,並確保它是最優的計劃(如確保有在計劃中沒有表掃描,如果優化它可以發生使用不好統計)

這裏有一些事情可以幫助:

  • Objects.Name添加索引 - 上NameTimeStamp甚至可能是一個複合索引。
  • rowidFTSObjects添加一個索引它尚不上Timestamp指數存在
  • UPDATE STATISTICS定期(最好經過大更新或每日更新是否連續)
  • 重建你的聚集索引(如果有的話)。如果您的聚簇索引位於不能順序插入的字段上(如一個char場,其中嵌在隨機的地方)
  • 不要select *,如果你不需要 - 增加I/O時間

威力也試着鑄造琴絃DATETIME,雖然我認爲SQL這是否暗示與數據轉換成一字符串(這不會使用索引上的日期時間)

SELECT * 
FROM Objects o, FTSObjects f 
WHERE f.rowid = o.AutoIncID AND 
    o.TimeStamp > CONVERT(DATETIME,'2012-07-11 14:24:16.582') AND 
    o.TimeStamp <= CONVERT(DATETIME,'2012-07-12 04:00:00.000') AND 
    o.Name='GPSHistory' 
ORDER BY o.TimeStamp 
LIMIT 100 
+0

我認爲我們的SQLite實現接受DateTime參數,但只是在內部使用字符串......不確定。 你有一個DBA的建議,讓我看看使用EXPLAIN QUERY PLAN命令。這讓我看到一個糟糕的索引被使用。 classname列已編入索引,但只有6個唯一名稱。我得到了使用Timestamp作爲索引的查詢,現在事情快了大約15倍。 –

2

是的,ORDER BYLIMIT之前被處理,但是這是正確的功能。否則,尋呼實際上不會起作用。但有一些想法用於優化。

  1. 如果不是絕對必要的,則不要SELECT *。我覺得它可能不是,因爲如果你分頁結果它幾乎肯定不會在表用戶正在尋找每一個領域。
  2. AutoIncID, TimeStamp創建覆蓋索引,以防止它讀取數據頁。如果它來自Objects,請將Name添加到該索引。
  3. rowid, Name,上創建一個覆蓋指數Name來自FTSObjects
  4. 如果返回的字段可以被限制,考慮增加這些領域的覆蓋指標如果這只是一對夫婦領域。您不希望索引變得太大,因爲那樣會影響寫入時間。
+1

解決方案必須使用錯誤的索引。該classname列只有六個唯一的名稱,並被編入索引。我強制使用時間戳索引,現在頁面在1秒內收集起來。我試圖創建覆蓋指數,但他們似乎並沒有改善... –