1. 程式人生 > 其它 >來實現一個DataStore的封裝吧

來實現一個DataStore的封裝吧

mysql索引

索引分類

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%'; 檢視全域性的索引使用情況