我不同意在其他答案中提出的主鍵的順序。
您的理想場景(對於您的確切示例查詢)是讓所有相關記錄彼此相鄰。這將啓用對您的數據的單一查詢。例如,使用(d1, s1, time)
作爲聚集主鍵,你就必須存儲的數據如下...
d1 | s1 | time
----+----+------
1 | 1 | 1234
1 | 1 | 1235 \
1 | 1 | 1236 SELECT * FROM table WHERE d1 = 1 AND s1 = 1 AND time BETWEEN 1235 AND 1237
1 | 1 | 1237 /
1 | 1 | 1238
1 | 2 | 1234
1 | 2 | 1235
1 | 2 | 1236
1 | 2 | 1237
1 | 2 | 1238
如果由其他人的建議,你有time
作爲第一個字段在羣集索引,你做不是在一個連續的塊中獲取你的所有數據。相反,你得到一個尋求每個人的時間價值......
time | d1 | s1
------+----+----
1234 | 1 | 1 *Desired Row 1
1234 | 1 | 2
1235 | 1 | 1 *Desired Row 2
1235 | 1 | 2
1236 | 1 | 1 *Desired Row 3
1236 | 1 | 2
1237 | 1 | 1 *Desired Row 4
1237 | 1 | 2
1238 | 1 | 1 *Desired Row 5
1238 | 1 | 2
這種結構實際上是一個不同的查詢非常好... ...
SELECT * FROM yourTable WHERE time = 1234 AND d1 = 1 AND s2 BETWEEN 2 AND 3
這表明,三項方是沒有單一的普遍完美聚簇索引。那麼,你怎麼選擇做什麼聚集,因爲你只能有一個聚集索引?
這取決於您的數據和您的查詢。對於每個查詢,您需要查看將要撤出的多少個不同連續的數據塊。儘量減少這些塊的數量是一個非常好的主意。但維護數據的順序也是如此,以便它適合GROUP BY或ORDER by子句。 JOIN進一步加強了這一點。
對於您的示例查詢,我建議的第一個索引確實是最好的。但不是所有的疑問。
另外,您需要考慮分段。數據存儲在頁面中,您需要考慮數據插入的方式(在考慮更新時將其視爲刪除和插入)。因爲可能是任何插入通常會比現有數據更新的時間值,首先在聚集索引中有time
會減少碎片。
例如,假裝每個頁面只能容納三行數據。上面建議的兩個索引看起來像這樣...
d1 | s1 | time time | d1 | s1
----+----+------ ------+----+----
1 | 1 | 1234 \ 1234 | 1 | 1 \
1 | 1 | 1235 Page 1 1234 | 1 | 2 Page 1
1 | 1 | 1236/ 1235 | 1 | 1 /
----+----+------ ------+----+----
1 | 1 | 1237 \ 1235 | 1 | 2 \
1 | 1 | 1238 Page 2 1236 | 1 | 1 Page 2
1 | 2 | 1234/ 1236 | 1 | 2 /
----+----+------ ------+----+----
1 | 2 | 1235 \ 1237 | 1 | 1 \
1 | 2 | 1236 Page 3 1237 | 1 | 2 Page 3
1 | 2 | 1237/ 1238 | 1 | 1 /
----+----+------ ------+----+----
1 | 2 | 1238 -Page 4 1238 | 1 | 2 -Page 4
現在,嘗試插入d1 = 1, s1 = 1, time = 1239
。
d1 | s1 | time time | d1 | s1
----+----+------ ------+----+----
1 | 1 | 1234 \ 1234 | 1 | 1 \
1 | 1 | 1235 Page 1 1234 | 1 | 2 Page 1
1 | 1 | 1236/ 1235 | 1 | 1 /
----+----+------ ------+----+----
1 | 1 | 1237 \ 1235 | 1 | 2 \
1 | 1 | 1238 Page 2 1236 | 1 | 1 Page 2
*1 | 1 | 1239*/ 1236 | 1 | 2 /
----+----+------ ------+----+----
1 | 2 | 1234 -Page 3 1237 | 1 | 1 \
----+----+------ 1237 | 1 | 2 Page 3
1 | 2 | 1235 \ 1238 | 1 | 1 /
1 | 2 | 1236 Page 4 ------+----+----
1 | 2 | 1237/ 1238 | 1 | 2 -Page 4
----+----+------ 1239 | 1 | 1 /
1 | 2 | 1238 -Page 5
左邊的版本不得不創建一個新頁面。右側的版本繼續填充現有頁面。
出現碎片時,經常會有維修計劃可以糾正碎片。這通常是一個過夜的過程。
這一切都有點複雜,不是嗎?那麼,關於這個話題就有整本書。
我通常不會過分擔心碎片,直到它成爲問題。但它確實值得記住。
請注意,在獨特(在您的情況下:主)鍵中使用_time_值被認爲是不好的做法。 – npe
好的,thx。任何想法我可以做什麼改變?順便說一句,任何PRAGMA設置,可以使這重複查詢更快一般? –