LIMIT 10000,10會發生什麼?

LIMIT分頁優化
進行分頁操作時,通常都會通過偏移量來查詢某些數據。然後再加上合適的order by子句, order by的列加上了索引,性能一般都不錯,而如果沒有對應的索引的話,MySQL則需要做大量的文件排序操作,對於文件排序操作,這裏有說明。

Limit 100000,10 會發生什麼?
Limit的語法是limit m,n 其中m是偏移量,n代表返回的數據條數。比如limit 0,3 就從第一條數據開始讀取後面三個數據(1,2,3 ),limit 2,3就從第三條數據開始讀取後面三個數據(3,4,5),但是不要以爲limit這樣操作會直接定位到第三條數據,還是會掃描前兩條數據。回到我們要回答的問題,由於100000這個數字非常大, 查詢這麼多條數據代價非常高,對於這種情況,有兩種辦法,一種就是頁面中限制分頁的數量,另外是優化大偏移量的性能。優化大偏移量的性能最簡單的方法是使用索引覆蓋掃描,還有的方法就是使用延遲關聯,它會讓MySQL掃描儘可能少的頁面,獲取需要訪問的記錄後再根據關聯列回表查詢需要的所有列。
MySQL中的排序優化
在MySQL中的ORDER BY有兩種排序方式:第一種是利用有序索引獲取有序數據,第二種是用文件排序。文件排序是一個成本很高的操作,應該儘量避免。當數據量比較小時,文件排序會在內存中進行,否則在磁盤上進行。文件排序有兩種排序算法:兩次傳輸排序和單次傳輸排序。兩次傳輸算法是舊版本使用的一種算法,原理是讀取行指針和需要排序的字段,對其進行排序,然後根據排序結果讀取所需要的數據行。這樣操作會進行兩次數據傳輸,第二次讀取的時候會產生大量的隨機I/O,成本極高。單次傳輸算法是新版本中的,原理是先讀取查詢所需要的所有列,然後再根據給定的列進行排序,最後返回結果。不再需要從數據表讀取兩次數據,只需要一次順序I/O讀取所有的數據,無須任何的隨機的I/O。缺點是如果需要返回的列非常的多,會額外佔用大量的空間。兩種算法都有各自的適用場景,沒有那種算法更爲高效的說法。在MySQL中有一個參數max_length_for_sort_data可以用來決定適用那種排序算法,當查詢所有列的總長度不超過這個參數時,MySQL適用單次傳輸排序算法,否則MySQL會選擇兩次傳輸排序算法。

磁盤搜索是巨大的性能瓶頸。當數據量變得非常大以致於緩存性能變得不可能有效
時,該問題變得更加明顯。對於大數據庫,其中你或多或少地隨機訪問數據,你可以確信
對讀取操作需要至少一次硬盤搜索,寫操作需要多次硬盤搜索。要想使該問題最小化,應
使用搜索次數較少的磁盤。
學習解釋EXPLAIN將幫助你瞭解MySQL優化器是如何工作的。要使用EXPLAIN,只需要在查詢的SELECT關鍵字之前加上EXPLIAN這個詞,MySQL會在查詢上設置一個標誌。當執行一個查詢時,這個標誌會使其返回在執行計劃中每一步的信息,而不是執行它。增加EXPLAIN時在查詢在FROM子句中包括子查詢的情況下,會執行子查詢。
們使用EXPLAIN解析SQL執行計劃時,如果有下面幾種情況,就需要特別關注下了:首先看下 type 這列的結果,如果有類型是 ALL 時,表示預計會進行全表掃描(full table scan)。通常全表掃描的代價是比較大的,建議創建適當的索引,通過索引檢索避免全表掃描。
  再來看下 Extra 列的結果,如果有出現 Using temporary 或者 Using filesort 則要多加關注:
  Using temporary,表示需要創建臨時表以滿足需求,通常是因爲GROUP BY的列沒有索引,或者GROUP BY和ORDER BY的列不一樣,也需要創建臨時表,建議添加適當的索引。
  Using filesort,表示無法利用索引完成排序,也有可能是因爲多表連接時,排序字段不是驅動表中的字段,因此也沒辦法利用索引完成排序,建議添加適當的索引。
  Using where,通常是因爲全表掃描或全索引掃描時(type 列顯示爲 ALL 或 index),又加上了WHERE條件,建議添加適當的索引。
其他狀態例如:Using index、Using index condition、Using index for group-by 則都還好,不用緊張。
EXPLAIN中的列總是10個列,分別是id、 select_type、 table、 type、 possible_keys、 key、key_len、 ref、 rows、 Extra,只有EXPLAIN EXTENDED在MySQL5.1增加了一個filtered列,EXPLAIN PARTITIONS 增加了一個Partitions列)。
Extra列
這一列包含的是不適合顯示在其他列的額外信息。Using index使用覆蓋索引。Using filesort代表在進行關聯查詢時用到了文件排序,並且ORDER BY子句中的所有的列都來自關聯的第一個表。MySQL在關聯處理第一個表的時候就進行文件排序。Using temporary;Using filesort代表會將關聯的結果先存放在一個臨時表中,等到所有的關聯都結束時,再進行文件排序。

CREATE TABLE grade(
Id int not null ,
Name varchar(10) ,
Level char(5),
Key(name)
);
EXPLAIN SELECT id from grade order by name limit 0,10;

EXPLAIN SELECT id from grade order by level limit 0,10;

type列
表示訪問類型,就是MySQL決定如何查找表中的行,下面的訪問方法依次從最差到最優。
all
最差的方法,利用全表掃描
index
這個跟全表掃描一樣,只是MySQL掃描表時按索引次序進行而不是行。他的主要優點是避免了排序。最大的缺點是要承擔按索引次序讀取整張表的開銷。意味着隨機次序訪問行,開銷很大。如果在Extra列中看到“Using index”,說明使用的是覆蓋索引。

range
範圍掃描就是一個有限制的索引掃描,開始於索引裏的某一點,返回匹配這個值域的行。比全索引掃描好一點,不用遍歷全部索引,當MySQL使用索引去查找一系列的值時,例如IN()和OR列表,也會顯示爲範圍查詢。
ref
這是一種索引訪問,返回所有匹配某個單個值的行,它是查找和掃描的混合體,此類索引訪問只有當使用了非唯一性索引或者唯一性索引的非唯一性前綴纔會發生。
eq_ref
使用這種索引查找,MySQL知道最多會只會返回一條符合條件的記錄。這種訪問方法只會在MySQL使用主鍵或者唯一性索引查找纔會看到。
const,system
當MySQL能夠對查詢的某一部分進行優化並將其轉換爲一個常量時,就會使用這些訪問類型。
NULL
這種方式意味着MySQL能夠在優化階段分解查詢語句,在執行階段甚至不用再訪問表或者索引。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章