簡體   English   中英

有效地選擇前n行

[英]Select top n rows efficiently

所以我有一張桌子,可能有數百萬行,

user   | points
---------------
user1  | 10
user2  | 12
user3  | 7
...

並希望SELECT * FROM mytable ORDER BY points LIMIT 100, 1000現在工作正常,但速度非常慢(在巨大的表上),因為它拒絕使用任何類型的索引,但執行全表掃描。 我怎樣才能提高效率呢?

我的第一個(顯而易見的)想法是在points DESC上使用索引,但后來我發現MySQL根本不支持這些。

接下來,我試圖反轉點上的符號,這意味着在點上基本上有一個升序索引,這也沒有幫助,因為它沒有使用索引進行排序

最后,我嘗試使用force index ,這幾乎沒有產生任何性能提升,因為它仍然取出整個表,但沒有排序(在EXPLAIN使用filesort:false)

我確信這一定是一個已解決的問題,但我沒有在網上找到任何有用的信息。 任何提示將不勝感激。

從查詢中獲得更好性能的一些方法。

永遠不要使用SELECT * 這是一個菜鳥的錯誤。 它基本上告訴查詢計划器它需要給你一切。 始終枚舉結果集中所需的列。 這是您想要的查詢(假設您沒有過分簡化您的問題)。

 SELECT user, points
   FROM table
  ORDER BY points
  LIMIT 100,1000

使用復合索引。 對於查詢, (points, user)上的復合索引將允許使用部分索引掃描來滿足您的查詢。 這應該比全表排序更快。 MySQL可以向后或向前掃描索引,因此您無需擔心降序

要添加正確的索引,請使用這樣的命令。

ALTER TABLE table ADD INDEX points_user (points, user);

編輯 反對在這里使用SELECT *的建議是基於(1)我未經證實的懷疑,即所討論的表格過於簡單並且在現實生活中有其他列,以及(2)有時索引必須精確匹配查詢的不方便的現實最佳表現結果。

我堅持認為,根據經驗,在具有性能敏感性的查詢中使用SELECT *並不是一個好的工程實踐(除非你非常喜歡查詢,否則你想要一次又一次地回到它)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM