2012-01-31 547 views
33

,我有以下形式的查詢:上時間戳創建索引優化查詢

SELECT * FROM MyTable WHERE Timestamp > [SomeTime] AND Timestamp < [SomeOtherTime] 

我想優化這個查詢,我想這會讓時間戳的索引,但我不當然,如果這會有所幫助。理想情況下,我希望爲聚簇索引創建時間戳,但MySQL不支持除主鍵之外的聚簇索引。

  • MyTable有4百萬行。
  • Timestamp實際上INT類型是。
  • 一旦行被插入,它永遠不會改變。
  • 與任何給定Timestamp行數平均爲約20,但也可以是高達200
  • 新插入的行具有Timestamp比大多數現有的行較大,但也可以是小於某些更新的行。

會在Timestamp索引幫我優化這個查詢?

+1

即使在MSSQL中,如果您在非唯一列上創建羣集索引,它也會在封面下使其具有唯一性。當然,索引會幫助選擇,但會減慢插入速度,索引將佔用磁盤空間。但這聽起來像你願意承擔的交易。將索引放在表格上並進行測試。索引用於>和<。 – Paparazzi 2012-01-31 22:22:30

+0

你在這張桌子上有聚集索引嗎? – 2012-01-31 22:24:54

+0

@BalamBalam我實際上是爲上述類型的查詢設計數據庫,所以我無法測試性能。 – DanielGibbs 2012-01-31 22:29:08

回答

36

。毫無疑問。沒有索引,您的查詢必須查看錶中的每一行。使用索引,就查找正確的行而言,查詢將是非常即時的。你付出的代價是在插入一個輕微性能降低;但那真的會很輕微。

+7

因此,獨特的時間戳數量相當高並且因此會產生相當大的索引是沒有缺點的? – DanielGibbs 2012-01-31 22:18:50

+1

瞬間它將是'如果[SomeOtherTime]' 和'[SomeTime]'之間的差異很小。 – 2012-01-31 22:21:19

+1

謝謝@ypercube - 只需在答案中限定:) - 我想說幾兆字節索引的缺點是值得的。數據庫擅長這樣的事情! – 2012-01-31 22:24:08

7

你絕對應該使用索引。 MySQL不知道這些時間戳的順序,爲了找到給定時間戳(或時間戳範圍)的記錄,需要查看每條記錄。而其中有400萬,這是相當多的時間!索引是你告訴MySQL關於你的數據的方式 - 「我會經常查看這個字段,所以保留一個我可以在哪裏找到每個值的記錄的列表。」

指標一般是定期查詢的領域是一個好主意。定義索引唯一的缺點是它們使用額外的存儲空間,所以除非你真的太緊張了,否則你應該嘗試使用它們。如果他們不適用,MySQL無論如何都會忽略它們。

4

如果你的查詢主要是利用這個時間戳記,你可以測試這個設計(擴大與時間戳作爲第一部分的主鍵):

CREATE TABLE perf (
    , ts INT NOT NULL 
    , oldPK 
    , ... other columns 
, PRIMARY KEY(ts, oldPK) 
, UNIQUE (oldPK) 
) ENGINE=InnoDB ; 

這將確保查詢,如您發佈的意志的一個正在使用羣集(主鍵)。

缺點是插入會慢一點。另外,如果表中還有其他索引,它們將使用更多的空間(因爲它們將包括4字節寬的主鍵)。

這種聚集索引的最大優點是具有大範圍掃描的查詢,例如必須閱讀大部分表格或整個表格的查詢才能按順序查找相關行,並按照想要的順序(BY timestamp)查找相關行,如果您想按日或周或月或年進行分組,則這也很有用。

舊的PK仍然可以用於通過對其保留UNIQUE約束來標識行。


您可能還需要在TokuDB看看,一個MySQL(和開源)變種,它允許multiple clustered indices

+0

這種方法的缺點是你現在需要知道時間戳以及老PK來找到一行PK。 – 2013-03-07 20:06:01

+0

@DavidHarkness不,如果舊PK仍然是唯一的。我將編輯答案以明確說明。 – 2013-03-07 23:53:34

+0

是的,有了新的獨特約束,你很好。如果按照時間戳進行聚類很重要,那麼成本可能是值得的。我將不得不考慮在我目前正在構建的系統中的兩個表,這些表本質上是用於報告的事務日誌。 – 2013-03-08 00:21:39

4

我不索引來提高選擇查詢時間的重要性不以爲然,但如果你能在其他鍵指數(並與這些指標的查詢),可能不需要,需要指數時間戳。

例如,如果你有timestampcategoryuserId表,它可能是更好的對userId創建一個索引來代替。在具有許多不同用戶的表格中,這將大大減少搜索時間戳的剩餘集合。

...如果我沒有弄錯,這樣做的好處是避免在每次插入時創建時間戳索引的開銷 - 在插入率高且具有高度唯一時間戳的表中,這可能是一個重要的考慮。

我與基於時間戳和其他鍵索引同樣的問題掙扎。我仍然有測試要做,所以我可以在我這裏說的背後加上證據。我會嘗試根據我的結果回發。

一種更好的解釋方案:

  1. 時間戳99%的獨特
  2. userId的80%,獨特的
  3. 類別25%的獨特

    • 索引時間戳將迅速減少查詢結果1%表格大小
    • userId上的索引將快速將查詢結果減少到2 0%的表大小
    • 索引的類別將迅速減少查詢結果以75%的表大小
    • 插入帶有時間戳指標將有很高的開銷**
    • 儘管我們的知識,我們的插入會尊重事實有增加時間戳,我沒有看到任何關於基於增量鍵的MySQL優化的討論。
    • 在userId上插入索引會產生相當高的開銷。
    • 帶有索引的類別插入將具有合理的低開銷。

**對不起,我不知道該用索引開銷或插入計算。