8.2.1.19 Optimizing LIMIT Queries 優化LIMIT 查詢:
如果你隻需要記錄的特定列從一個結果集,使用一個LIMIT 子句在一個查詢裡,
而不是擷取整個結果集,扔掉額外的資料。
MySQL 有時候優化一個查詢有一個LIMIT row_count 子句,沒有HAVING 子句:
如果你隻選擇一小部分的記錄使用LIMIT,MySQL 使用indexed 在一些例子裡,
通常它甯願選擇做一個全表掃描:
如果你結合LIMIT row_count 和ORDER BY,MySQL 結束排序在它發現第一個row_count ,
而不是整個結果 。如果排序是通過使用一個索引,這是很快的。
如果一個filesort 必須被做, 所有比對查詢的記錄沒有LIMIT 子句是被選擇的,
大多數或者全部被存儲, 在row_count 被找到前。
在初始的記錄被找到後,MySQL 不排序任何剩餘的結果集。
這種行為的一種表現是ORDER BY 查詢使用和不使用LIMIT 可能傳回記錄按不同的順序
在後面的章節描述:
如果你組合LIMIT row_count 使用DISTINCT, MySQL 隻要找到row_count unique 記錄就停止。
在一些例子中,一個GROUP BY 可以通過讀取index 來解決按順序(或者在索引上做一個排序)
然後計算彙總直到Index value 改變。在這種情況下,LIMIT row_count 不計算任何不需要GROUP BY 的值
當MySQL 已經發送 需要的記錄給用戶端, 它終止查詢除非你使用SQL_CALC_FOUND_ROWS.
行數然後檢索用SELECT FOUND_ROWS().
LIMIT 0 快速的傳回一個空的結果集, 這個可以用于檢查一個查詢的正确性。
它也可以被用來獲得結果列的類型 如果你使用一個MySQL API,
使結果集資料可用。 與mysql 用戶端程式, 你可以使用–column-type-info 選項來顯示結果列類型。
如果server 使用臨時表來解決查詢,它使用LIMIT row_count 子句來計算需要的空間。
如果多行具有相同的值在ORDER BY 列裡, server 可以自由的傳回繼續以任何的排序,
并根據總體的執行計劃來進行不同的方式,換句話說,這些行的排序順序是不确定的。
一個因素影響執行計劃是LIMIT, 因為一個ORDER BY 查詢 有和沒有LIMIT 可能傳回不同順序的記錄。
考慮這個查詢, 是按類型列排序,但是不确定是相對于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 可能影響每一類值的記錄的順序,例如, 這是一個正确的查詢結果:
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 |
+—-+———-+——–+
在每一種情況下, 記錄按ORDER BY 列排序, 這是SQL标準需要的:
如果它是重要的 确認相同的記錄有和沒有LIMIT,包括額外的列 在ORDER BY 子句來确定順序。
比如,如果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 |
+—-+———-+——–+
在MySQL 5.6.2, 優化器會更有效的處理查詢(子查詢)如下:
SELECT … FROM single_table … ORDER BY non_index_column [DESC] LIMIT [M,]N;
這種類型的查詢是常見的,顯示少數行從一個大的結果集:
SELECT col1, … FROM t1 … ORDER BY name LIMIT 10;
SELECT col1, … FROM t1 … ORDER BY RAND() LIMIT 15;
sort buffer 有一個sort_buffer_size參數,如果sort 原理用于N條記錄是足夠小的 放入sort buffer
(M+N 記錄如果M被指定), server 可以避免使用一個合并檔案,執行整個排序在記憶體裡
通過處理sort buffer 作為優化隊列