2017-05-18 60 views
3

我有兩個表usersposts每個500k記錄。爲什麼索引不加快這個查詢?

我想找到寫過100到200個帖子的用戶。

我的查詢是:

SELECT u.accountid, COUNT(*) 
FROM users u 
JOIN posts p 
ON u.accountid = p.owneruserid 
GROUP BY u.accountid 
HAVING COUNT(*) BETWEEN 100 AND 200; 

而且我在一秒鐘得到答案。

我在usersposts表中分別在accountidowneruserid字段中添加了索引,但查詢沒有加快。爲什麼?

+1

1秒似乎很合理。 –

+0

解釋分析 –

+0

@GordonLinoff它只適用於測試。我只是不明白爲什麼索引根本沒有幫助 – user4230877

回答

3
HAVING COUNT(*) BETWEEN 100 AND 200; 

該部分是解釋爲什麼索引是徒勞的關鍵。

我們只需要獲得成員數在100到200之間的組。這意味着對於每個組我們需要成員的確切數量。第二點我們沒有任何限制(例如WHERE部分),以便獲取計數和我們需要通過表中所有記錄的所有組。

索引例如B-Tree索引有助於根據索引條件查找適當的元素(行)。如果數據以某種方式排序(索引提供順序),我們可以使用二分搜索來查找所需的子集。但在我們的情況下,我們需要掃描所有記錄。因此,他們是否下令並不重要。

這就是爲什麼索引不加快查詢。

+0

答案我需要。非常感謝你 – user4230877

1

可以簡化查詢:

SELECT p.owneruserid, COUNT(*) 
FROM posts p 
GROUP BY p.owneruserid 
HAVING COUNT(*) BETWEEN 100 AND 200; 

posts(owneruserid)的指數應該爲這個查詢工作。它是查詢的覆蓋索引,所以查詢可能稍快一點。

總的來說,查詢似乎需要掃描posts中的所有數據以進行聚合。 HAVING無法利用索引。但是,查詢可以使用覆蓋索引來減少I/O。

+0

如果數據有差異,可能會帶來不正確的結果。但是,然後OP有更多的問題。 –

+1

索引無法正常工作。它要求'具有100和200之間的計數(*)',這要求全掃描具有所有計數。 – StanislavL

+0

但是,如果他將計數結果放在臨時表中,然後計算在100和200之間...那麼工作速度會更快然後計數子句?從來沒有測試過,所以不得不問 – Veljko89

相關問題