1. 程式人生 > >20.MySQL優化LIMIT Query Optimization

20.MySQL優化LIMIT Query Optimization

介紹

如果只需要結果集中指定數量的行,請LIMIT在查詢中使用子句,而不是獲取整個結果集並丟棄額外資料。

MySQL可以優化包含 LIMIT row_count 但沒有HAVING的查詢

  • 假如使用LIMIT掃描少數行,MySQL在某些情況下使用索引,通常情況下它更喜歡進行全表掃描。
  • 假如LIMIT與ORDER BY進行組合,MySQL會在找到排序結果的第一行後立即停止排序 ,而不是對整個結果進行排序。如果使用索引完成排序,則速度非常快。如果必須進行一個filesort ,選擇與查詢匹配的所有行不做LIMIT限制,並在找到第一個之前對其中的大部分或全部進行排序 。在找到初始行之後,MySQL不會對結果集的任何剩餘部分進行排序。
  • 假如LIMIT row_count與DISTINCT組合,MySQL當查詢到了row_count數量的資料後立馬停止。
  • 在某些情況中,GROUP BY可以通過按順序讀取索引排序(或者在索引排序),然後計算摘要直到索引值更改。
  • 一旦MySQL向客戶端傳送了所需的行數,它就會中止查詢,除非您使用 SQL_CALC_FOUND_ROWS。在這種情況下,可以使用檢索行數SELECT FOUND_ROWS()。
  • LIMIT 0會馬上返回一個空集合,這對於檢查查詢的有效性非常有用。它還可用於獲取使用MySQL API的應用程式中的結果列型別,該API使結果集元資料可用。使用 mysql客戶端程式,您可以使用該 --column-type-info選項顯示結果列型別。
  • 假如伺服器使用臨時表來解決查詢,他會使用 LIMIT row_count 來計算使用空間。
  • 假如一個ORDER BY查詢無法使用索引,但是此語句包含LIMIT,則優化器可能能夠避免使用合併檔案並使用記憶體中filesort操作對記憶體中的行進行排序 。

當ORDER BY多個列時,則伺服器可以按任何順序自由返回這些行,並且可能會根據整體執行計劃的不同而不同。換句話說,這些行的排序順序相對於無序列是不確定的。

影響執行計劃的一個因素是 LIMIT,因此ORDER BY 帶有和不帶的查詢LIMIT可能會返回不同順序的行。考慮這個查詢,它按category列排序,但對於id和 rating列是不確定的:

mysql> SELECT * FROM ratings ORDER BY category;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  3 |        2 |    3.7 |
|  4 |        2 |    3.5 |
|  6 |        2 |    3.5 |
|  2 |        3 |    5.0 |
|  7 |        3 |    2.7 |
+----+----------+--------+

包括LIMIT可能影響每個category值內的行的順序。例如,這是一個有效的查詢結果:

mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  4 |        2 |    3.5 |
|  3 |        2 |    3.7 |
|  6 |        2 |    3.5 |
+----+----------+--------+

如果確保使用和不使用相同的行順序很重要,請LIMIT在ORDER BY子句中包含其他列以使訂單具有確定性。例如,如果id值是唯一的,則可以通過如下排序category按id順序顯示給定值的行 :

mysql> SELECT * FROM ratings ORDER BY category, id;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  3 |        2 |    3.7 |
|  4 |        2 |    3.5 |
|  6 |        2 |    3.5 |
|  2 |        3 |    5.0 |
|  7 |        3 |    2.7 |
+----+----------+--------+

mysql> SELECT * FROM ratings ORDER BY category, id LIMIT 5;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  3 |        2 |    3.7 |
|  4 |        2 |    3.5 |
|  6 |        2 |    3.5 |
+----+----------+--------+