**優化**
查詢優化、索引優化、庫表結構優化
# 6.2 慢查詢基礎:優化數據訪問
1.確認應用程序是否在檢索大量超過需要的數據。這通常意味著訪問了太多的行,但有時候也可能是訪問了太多的列。
2.確認MySQL服務器層是否分析大量超過需要的數據行
**查詢不需要的記錄**
例如在新聞網站中取出100條記錄,但是只是在頁面上顯示前面10條)。他們認為MySQL會執行查詢,并只返回他們需要的10條數據,然后停止查詢。實際情況是MySQL會查詢出全部的結果集,客戶端的應用程序會接收全部的結果集數據,然后拋棄其中大部分數據。最簡單有效的解決方法就是在這樣的查詢后面加上LIMIT。
**多表關聯時返回全部列**
查詢所有在電影Academy Dinosaur中出現的演員
比如:

應該:

如果應用程序使用了某種緩存機制,獲取并緩存所有的列的查詢,相比多個獨立的只獲取部分列的查詢可能就更有好處。
**重復查詢相同的數據**
比較好的方案是,當初次查詢的時候將這個數據緩存起來,需要的時候從緩存中取出,這樣性能顯然會更好
## 6.2.2 MySQL是否在掃描額外的記錄
衡量查詢開銷:

這三個指標都會記錄到MySQL的慢日志中,所以檢查慢日志記錄是找出掃描行數過多的查詢的好辦法。
**響應時間:**
見書
**掃描的行數和返回的行數**
理想情況下掃描的行數和返回的行數應該是相同的。但實際情況中這種“美事”并不多。例如在做一個關聯查詢時,服務器必須要掃描多行才能生成結果集中的一行。掃描的行數對返回的行數的比率通常很小
在EXPLAIN語句中的type列反應了訪問類型,掃描表、掃描索引、范圍訪問和單值訪問,速度從慢到快。
一般MySQL能夠使用如下三種方式應用WHERE條件,從好到壞依次為:
?在索引中使用WHERE條件來過濾不匹配的記錄。這是在存儲引擎層完成的。
?使用索引覆蓋掃描(在Extra列中出現了Using index)來返回記錄,直接從索引中過濾不需要的記錄并返回命中的結果。這是在MySQL服務器層完成的,但無須再回表查詢記錄。
?從數據表中返回數據,然后過濾不滿足條件的記錄(在Extra列中出現Using Where)。這在MySQL服務器層完成,MySQL需要先從數據表讀出記錄然后過濾。
*****
type列
MySQL找到數據行的方式,即訪問類型。效率從最差到最好的順序如下:
ALL
全表掃描,沒有用到任何的索引,這是一種非常原始的查找方法,非常的耗時二號抵消。
index
這種類型只是另一種形式的全部掃描,只不過它的掃描順序是按照索引的順序,然后根據索引回表取數據。和All相比,他們都是取得了全表的數據,而且index要先讀索引再回表取數據。
如果連接類型為type,而且extra列中的值為‘Using index’,那么稱這種情況為索引覆蓋。
rang
rang指的是有范圍的索引掃描,相交于index的全索引掃描,它有范圍限制,因此要優于index。
它是基于索引的,表示WHERE條件中對索引列使用了BETWEEN AND、>、 <、 IN、OR。
ref
查找條件使用索引而且不為主鍵或unique。表示雖然使用了索引,但該索引列的值不唯一,有重復。這樣即使使用索引找到了第一條數據,仍然需要進行目標值附近的小范圍掃描,但它的好處是不用全表掃描。
-ref_eq
進行精確查詢,結果集唯一,表示使用了主鍵或唯一性索引查找的情況。
const,system
當MySQL能對查詢部分進行優化,并且轉換為一個常量。比如,where條件使用主鍵查詢。
extra列
這一列包含的是不在其他列顯示的額外信息。
using index
這個說明MySQL使用覆蓋索引,避免了回表操作,效率不錯。
using where
服務器在存儲引擎收到行后會進行過濾。即會根據查詢條件過濾結果集。
這表示服務器在存儲引擎返回行以后再應用WHERE過濾條件。
using file sort
表示排序的時候沒有用到索引,不得不采取其他方式排序。排序方法有內存排序,在臨時文件排,采用雙路排序法,或者是采用整行排序等,using file sort并沒有說是那些排序方法。
using temporay
表示用到了一張臨時表,至于臨時表是在內存中還是在磁盤上就不知道了。
*****