天天看點

8.2.1.19 Optimizing LIMIT Queries 優化LIMIT 查詢:

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 作為優化隊列