sql的編寫語法是這樣的:mysql
SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOIN <right_table> ON <join_condition> WHERE <where_condition> GROUP BY <group_by_list> HAVING <having_condition> ORDER BY <order_by_condition> LIMIT <limit_condition>
MySQL讀取的順序是這樣的:ios
FROM <left_table> ON <join_condition> <join_type> JOIN <right_table> WHERE <where_condition> GROUP BY <group_by_list> HAVING <having_condition> SELECT DISTINCT <select_list> ORDER BY <order_by_condition> LIMIT <limit_condition>
MySQL官方對索引的定義:索引是幫助MySQL高效獲取數據的數據結構;索引的目的在於提升查詢效率,能夠相似字典;排好序的快速查找的數據結構;索引會影響where
後面的查詢和order by
後面的排序;通常來講索引自己也很大,不可能所有存儲在內存中,所以索引每每會以索引文件的形式存儲在磁盤上;頻繁增刪改的表不適合建索引;sql
索引優點:數據庫
提升數據檢索的效率,下降數據庫的IO成本;經過索引列對數據進行索引,下降數據排序的成本,下降CPU的消耗;緩存
索引的劣勢:bash
實際上索引也是一張表,該表保存了主鍵與索引字段,並指向實體表的記錄,因此索引列也是要佔用空間的;雖然索引大大提升了查詢速度,但會下降更新表的速度,如對錶進行INSERT,UPDATE和DELETE;由於更新表時,MySQL不只要保存數據,還要保存索引文件每次更新添加的索引列字段,都會調整由於更新所帶來的鍵值變化後的索引信息;服務器
適合創建索引的狀況:數據結構
1.主鍵自動創建惟一索引 2.頻繁做爲查詢條件的字段應該創建索引 3.查詢中與其餘表關聯的字段,外鍵關係創建索引 4.頻繁更新的字段不適合創建索引,由於每次更新不單是更新了記錄還會更新索引結構; 5.where條件裏用不到的字段不建立索引 6.查詢中排序的字段,排序字段若經過索引去訪問將大大提升排序速度 7.查詢中統計或分組的字段
不適合建立索引的狀況:性能
1.表記錄太少不適合創建索引; 2.常常增刪改的表不適合創建索引;提升了查詢速度,同時卻會更新表的速度,如對錶進行插入操做,由於更新表時,MySQL不只要保存數據,還要保存表的索引結構; 3.數據重複且分佈均勻的表的字段不適合創建索引,所以應該只爲最常常查詢的和最常常排序的數據創建索引;注意,若是某個數據列包含重複的內容,爲它創建的索引就沒有太大的效果;
MySQL常見的性能瓶頸:優化
1.CPU:CPU在飽和的時候通常會發生在數據裝入內存或從磁盤上讀取數據時候 2.IO:磁盤I/O瓶頸發生在裝入數據遠大於內存容量的時候 3.服務器硬件的性能瓶頸:top, free, iostat和vmstat來查看系統性能狀態
EXPLAIN用途:
1.表的讀取順序 2.數據讀取操做的操做類型 3.哪些索引可使用 4.哪些索引被實際使用 5.表之間的引用 6.每張表有多少行被優化器查詢
EXPLAIN字段解釋:
三種狀況:
從最好到最差依次是:
system>const>eq_ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL
system>const>eq_ref>ref>range>index>ALL
system:表只有一行記錄(等於系統表),這是const類型的特列,平時不會出現,這個也能夠忽略不計
const:表示經過索引一次就找到了,const用於比較primary key或unique索引,由於只匹配了一行數據,因此很快;若是將主鍵置於where列表中,MySQL就能將該查詢轉換爲一個常量
eq_ref:惟一性索引掃描,對於每一個索引鍵,表中只有一條記錄與之匹配;常見於主鍵或惟一索引;
ref:非惟一性縮影掃描,返回匹配某個單獨值的全部行;本質上也是一種索引訪問,它返回全部匹配某個單獨值的行,然而,它可能會找多個符合條件的行,因此它應該屬於查找和掃描的混合體;
range:只檢索給定範圍的行,使用一個索引來選擇行,key列顯示使用了哪一個索引;通常就是在where語句中出現了between,<,>,in等的查詢;這種範圍掃描索引比全表掃描要好,由於它只須要開始於索引的某一點,結束於某一點,不用掃描所有索引;
index:index與ALL區別爲index類型只遍歷索引樹;這一般比ALL快,由於索引文件一般比數據文件小(all和index都是讀全表,但index是從索引中讀取的,而all從硬盤中讀出來的)
all:將遍歷全表以找到匹配的行
using filesort:說明mysql會對數據使用一個外部的索引排序,而不是按照表內的索引排序進行讀取;mysql中沒法利用索引完成的排序操做稱爲文件排序;
using temporary:使用了臨時表保存中間結果,mysql在對查詢結果排序時使用臨時表,經常使用於排序order by和分組查詢group by
using index:表示相應的select操做中使用了覆蓋索引,避免了訪問表的數據行;若是同時出現using where,代表索引被用來執行索引的鍵值查找;若是沒有同時出現using where,代表索引用來讀取數據而非執行查找操做;
覆蓋索引的理解方式:
1.select的數據列只用從索引列中就可以得到,沒必要讀取數據行,MySQL能夠利用索引返回select列表中的字段,而沒必要根據索引再次讀取數據文件;查詢列要被所建的索引覆蓋
2.索引是高效找到行的一個方法,可是通常數據庫也能使用索引找到一個列的數據,所以它沒必要讀取整個行;畢竟索引葉子節點存儲了它們的索引數據,當能經過讀取索引就能夠獲得想到的數據,那就不須要讀取行,一個索引包含了(或覆蓋了)知足查詢結果的數據叫做覆蓋索引
注意:若是要使用覆蓋索引,必定要注意select列表中只取出須要的列,不可select *,若是將全部字段一塊兒作索引會致使索引文件過大,查詢性能降低;
using where:代表使用where過濾
using join buffer:使用了鏈接緩存
當使用left join時,左表是驅動表,右表是被驅動表
當使用right join時,右表時驅動表,左表是被驅動表
impossible where:where子句的值老是false,不能用來獲取任何元組
select tables optimized away:在沒有group by子句的狀況下,基於索引優化MIN/MAX操做或對於MyISAM存儲引擎優化COUNT(*) 操做,沒必要等到執行階段再進行計算,cha'x執行計劃生成的階段完成優化;
distinct:優化distinct,在找到第一匹配的元組後即中止找相同值的工做