來實現一個DataStore的封裝吧
索引分類
1.單列索引:即一個索引只包含單個列,一個表可以有多個單列索引
2.唯一索引:索引列的值必須唯一,但允許有空值
3.複合索引:即一個索引包含多個列
建立、檢視、刪除、修改索引
建立索引
create index idx_city_name on city(name);
create index idx_city_name_email_status on city(name,email,status);
檢視索引
show index from city;
刪除索引
drop index idx_city_name on city;
alter命令
alter table city add primary key(id) 新增主鍵索引
alter table city add unique idx_city_name(name) 建立唯一索引
alter table city add index idx_city_name(name) 新增普通索引,索引值可以出現多次
alter table city add fulltext idx_city_name(name) 指定索引為fulltext,用於全文索引
explian 分析語句
1、id select查詢的序列號,是一組數字,表示的是查詢中執行select子句或者是操作表的順序。
2、select_type 表示select的型別
simple(簡單表,既不使用表連線或者子查詢)
primary(查詢中若包含任何複雜的子查詢,最外層查詢標記為該標識)
subquery(在select或where列表中包含了子查詢)
derived(在from列表中包含了子查詢,被標記為derived(衍生)mysql會遞迴執行這些子查詢, 把結果放在臨時表中)
UNION(若第二個select出現在union之後,則標記為union;若union包含在from子句的子查詢中,外層select將被標記為:derived)
union result (從union表獲取結果的select)
3、table 輸出結果集的表
4、type 表示表的連線型別,效能由好到差的連線型別為(system--->const---->eq_ref---->ref---->ref_or_null--->index_merge--->index_subquery--->range--->index--->all)
null mysql不訪問任何表,索引,直接返回結果
system 表只有一行記錄(等於系統表),這是const型別的特列,一般不會出現
const 表示通過索引一次就找到了,const用於比較primary key或者unique索引。因為只匹配一行資料,所以很快。如將主鍵置於where列表中,mysql就能將該查詢轉換為一個常量。const於將“主鍵”或“唯一”索引的所有部分與常量值進行比較
eq_ref 類似ref,區別在於使用的是唯一索引,使用主鍵的關聯查詢,關聯查詢出的記錄只有一條。常見於主鍵或唯一索引掃描
ref 非唯一索引掃描,返回匹配某個單獨值的所有行。本質上也是一種索引訪問,返回所有匹配某個單獨值的所有行(多個)
range 值檢索給定返回的行,使用一個索引來選擇行。where之後出現between,<,>,in等操作。
index index與all的區別為index型別只是遍歷了索引樹,通常比ALL快,ALL是遍歷資料檔案。
all 將遍歷全表以找到匹配的行
5、possible_keys* 表示查詢的時候,可能使用的索引
6、key 表示實際使用的索引
7、key_len索引欄位的長度
8、rows 掃描行的數量
9、extra 執行情況的說明和描述
using-filesort 說明mysql會對資料使用一個外部的索引排序,而不是按照表內的索引順序進行讀取,稱為“檔案排序”
using temporary 使用了臨時表儲存中間結果,mysql在對查詢結果排序時使用臨時表。常見於order by 和group by
using index 表示相應的select操作使用了覆蓋索引,避免訪問表的資料行,效率不錯。
show profile 分析sql
mysql從5.0.37版本開始增加對show profiles和show profile語句的支援。show profiles能夠在做SQL優化時幫助我們瞭解時間都耗費到哪裡去了。
select @@have_profiling;
通過have_profiling引數,能夠看到當前MYSQL是否支援profile:
select @@profiling;檢視是否開啟
預設profiling是關閉的,可以通過set語句在session級別開啟profiling;
set profiling =1;開啟profiling開關;
show profiles;檢視sql
show profilie for query 1;分析id為1的sql
sending data狀態表示mysql執行緒開始訪問資料行並把結果返回給客戶端,而不僅僅是返回給客戶端。由於在sending data狀態下,mysql執行緒往往需要做大量的磁碟讀取操作,所以經常是整個查詢中耗時最長的狀態。
show profilie cup for query 1;
1.status sql語句執行的狀態
2.duration sql執行過程中每一個步驟的耗時
3.cpu_user
4.cpu_system
trace分析優化器執行計劃
mysql5.6提供了對SQL的跟蹤trace,通過trace檔案能夠進一步瞭解為什麼喲花錢選擇A計劃而不是B計劃。
開啟trace,設定格式為JSON,並設定trace最大能夠使用的記憶體大小,避免解析過程中因為預設記憶體過小而不能夠完整展示。
set optimizer_trace="enabled=on",end_markers_in_json=on;
set optimizer_trace_max_mem_size=1000000;
執行sql語句
select * from A where age < 5
最後檢查information_schema.optimizer_trace就可以知道mysql是如何執行SQL的
select * from information_schema.optimizer_trace\G;
複合索引索引失效
1.不滿足最左匹配原則
2.範圍索引列沒有放在最後
3.使用了select *
4.索引列上有計算
5.索引列上使用了函式
6.字元型別沒加引號,底層在隱式轉換
7.用is null和is not null沒注意欄位是否允許為空
如果欄位不允許為空,則is null 和 is not null這兩種情況索引都會失效。
如果欄位允許為空,則is null走 ref 型別的索引,而is not null走 range 型別的索引。
8.like查詢左邊有%
9.使用or關鍵字 ,如果有一邊條件不是索引,那麼索引失效,使用union替代
10.not in 在mysql5.7索引會失效,mysql5.8使用range型別索引
11.<> != 在mysql5.7索引會失效,mysql5.8使用range型別索引 使用大於小於替代不等於
12.mysql 通過索引掃描的行記錄數超過全表的10%~30% 左右,優化器也可能不會走索引,自動變成全表掃描。
13.有沒有使用索引跟 where 後面的條件有關,而跟 order by 後面的欄位沒關係 ,而需不需要按檔案重排序,則跟 order by 後面的欄位有直接關係
單列索引和複合索引使用選擇
儘量使用複合索引,而少使用單列索引。
建立複合索引
create index idx_name_sta_address on tb_seller(name,status,address);
就相當於建立了三個索引:
name
name + status
name + status +address
建立單列索引
create index idx_seller_name on tb_seller(name);
create index idx_seller_status on tb_seller(status);
create index idx_seller_address on tb_seller(address);
資料庫會選擇一個最優的索引來使用,並不會使用全部索引。
檢視索引使用情況
show status like 'handler_read%'; 檢視當前會話的索引使用情況
show global status like 'handler_read%'; 檢視全域性的索引使用情況