Python學習 Day 056 - MySql - 索引
阿新 • • 發佈:2018-11-23
主要內容;
- 1.索引介紹
- 2.常見的幾種索引
- 3.索引名詞
- 4.最左字首
- 5.正確使用索引
- 6.索引的注意事項
- 7.執行計劃
1.索引介紹
資料庫中專門用於幫助使用者快速查詢資料的一種資料結構。類似於字典中的目錄,查詢字典內容時可以根據目錄查詢到資料的存放位置嗎,然後直接獲取。
索引的作用:約束和加速查詢
2.常見的幾種索引
- 普通索引 - 唯一索引 - 主鍵索引 - 聯合索引(多列) - 聯合主鍵索引 - 聯合唯一索引 - 聯合普通索引
無索引: 從前往後一條一條查詢 有索引:建立索引的本質,就是建立額外的檔案(某種格式儲存,查詢的時候,先去格外的檔案找,定好位置,然後再去原始表中直接查詢。但是建立索引越多,會對硬碟也是有損耗。 建立索引的目的: a.額外的檔案儲存特殊的資料結構 b.查詢快,但是插入更新刪除依然慢 c.建立索引之後,必須命中索引才能有效 無索引和有索引的區別以及建立索引的目的
#索引的種類 hash索引和BTree索引 (1)hash型別的索引:查詢單條快,範圍查詢慢 (2)btree型別的索引:b+樹,層數越多,資料量指數級增長(我們就用它,因為innodb預設支援它
2.1 普通索引
#建立表 & 普通索引 create table userinfo( nid int not null auto_increment primary key, name varchar(32) not null, email varchar(建立表&普通索引64) not null, index ix_name(name) );
#普通索引 create index 索引的名字 on 表名(列名)
#刪除索引 drop index 索引的名字 on 表名
#檢視索引 show index from 表名
2.2唯一索引
#建立表 & 唯一索引 create table userinfo( id int not null auto_increment primary key, name varchar(建立表 &唯一索引32) not null, email varchar(64) not null, unique index ix_name(name) );
#唯一索引 create unique index 索引名 on 表名(列名)
#刪除唯一索引 drop index 索引名 on 表名;
2.3主鍵索引 (加速查詢和唯一約束)(不含null)
#主鍵索引 create table userinfo( id int not null auto_increment primary key, name varchar(32) not null, email varchar(64) not null, unique index ix_name(name) ) or create table userinfo( id int not null auto_increment, name varchar(32) not null, email varchar(64) not null, primary key(nid), unique index ix_name(name) ) 建立表+主鍵索引建立表和設定主鍵索引
# 主鍵索引 alter table 表名 add primary key(列名);
#刪除主鍵索引 alter table 表名 drop primary key; alter table 表名 modify 列名 int, drop primary key;
2.4 組合索引
組合索引是將n個列組合成一個索引
其應用場景為:頻繁的同時使用n列來進行查詢,如:where name = 'alex' and email = '[email protected]'。
#聯合普通索引 create index 索引名 on 表名(列名1,列名2);
3.索引名詞
#覆蓋索引:在索引檔案中直接獲取資料 例如: select name from userinfo where name = 'alex50000'; #索引合併:把多個單列索引合併成使用 例如: select * from userinfo where name = 'alex13131' and id = 13131;
4.最左字首
最左字首匹配: create index ix_name_email on user(name,email); select * from userinfo where name = 'alex'; select * from userinfo where name = 'alex' and email='[email protected]'; select * from userinfo where email='[email protected]'; 如果使用組合索引如上,name和email組合索引之後,查詢 (1)name和email ---使用索引 (2)name ---使用索引 (3)email ---不適用索引 對於同時搜尋n個條件時,組合索引的效能好於多個單列索引 ******組合索引的效能>索引合併的效能*********
5.正確使用索引
- 命中索引
- 正確使用索引 (避免)
- like '%xx' select * from userinfo where name like '%al'; - 使用函式 select * from userinfo where reverse(name) = 'alex333'; - or select * from userinfo where id = 1 or email = '[email protected]'; 特別的:當or條件中有未建立索引的列才失效,以下會走索引 select * from userinfo where id = 1 or name = 'alex1222'; select * from userinfo where id = 1 or email = '[email protected]' and name = 'alex112' - 型別不一致 如果列是字串型別,傳入條件是必須用引號引起來,不然... select * from userinfo where name = 999; - != select count(*) from userinfo where name != 'alex' 特別的:如果是主鍵,則還是會走索引 select count(*) from userinfo where id != 123 - > select * from userinfo where name > 'alex' 特別的:如果是主鍵或索引是整數型別,則還是會走索引 select * from userinfo where id > 123 select * from userinfo where num > 123 - order by *** select email from userinfo order by name desc; 當根據索引排序時候,選擇的對映如果不是索引,則不走索引 特別的:如果對主鍵排序,則還是走索引: select * from userinfo order by nid desc; - 組合索引最左字首 如果組合索引為:(name,email) name and email -- 使用索引 name -- 使用索引 email -- 不使用索引
6.索引的注意事項
(1)避免使用select * (2)count(1)或count(列) 代替count(*) (3)建立表時儘量使用char代替varchar (4)表的欄位順序固定長度的欄位優先 (5)組合索引代替多個單列索引(經常使用多個條件查詢時) (6)儘量使用短索引 (create index ix_title on tb(title(16));特殊的資料型別 text型別) (7)使用連線(join)來代替子查詢 (8)連表時注意條件型別需一致 (9)索引雜湊(重複少)不適用於建索引,例如:性別不合適
7.執行計劃
select_type: 查詢型別 SIMPLE 簡單查詢 PRIMARY 最外層查詢 SUBQUERY 對映為子查詢 DERIVED 子查詢 UNION 聯合 UNION RESULT 使用聯合的結果 table: 正在訪問的表名 type: 查詢時的訪問方式,效能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const ALL : 全表掃描,對於資料表從頭到尾找一遍 select * from userinfo; 特別的:如果有limit限制,則找到之後就不在繼續向下掃描 select * from userinfo where email = '[email protected]' select * from userinfo where email = '[email protected]' limit 1; 雖然上述兩個語句都會進行全表掃描,第二句使用了limit,則找到一個後就不再繼續掃描。 INDEX :全索引掃描,對索引從頭到尾找一遍 select nid from userinfo; RANGE: 對索引列進行範圍查詢 select * from userinfo where name < 'alex'; PS: between and in > >= < <= 操作 注意:!= 和 > 符號 INDEX_MERGE: 合併索引,使用多個單列索引搜尋 select * from userinfo where name = 'alex' or nid in (11,22,33); REF: 根據索引查詢一個或多個值 select * from userinfo where name = 'alex112'; EQ_REF: 連線時使用primary key 或 unique型別 select userinfo2.id,userinfo.name from userinfo2 left join tuserinfo on userinfo2.id = userinfo.id; CONST:常量 表最多有一個匹配行,因為僅有一行,在這行的列值可被優化器剩餘部分認為是常數,const表很快,因為它們只讀取一次。 select id from userinfo where id = 2 ; SYSTEM:系統 表僅有一行(=系統表)。這是const聯接型別的一個特例。 select * from (select id from userinfo where id = 1) as A; possible_keys:可能使用的索引 key:真實使用的 key_len: MySQL中使用索引位元組長度 rows: mysql估計為了找到所需的行而要讀取的行數 ------ 只是預估值 extra: 該列包含MySQL解決查詢的詳細資訊 “Using index” 此值表示mysql將使用覆蓋索引,以避免訪問表。不要把覆蓋索引和index訪問型別弄混了。 “Using where” 這意味著mysql伺服器將在儲存引擎檢索行後再進行過濾,許多where條件裡涉及索引中的列,當(並且如果)它讀取索引時,就能被儲存引擎檢驗,因此不是所有帶where子句的查詢都會顯示“Using where”。有時“Using where”的出現就是一個暗示:查詢可受益於不同的索引。 “Using temporary” 這意味著mysql在對查詢結果排序時會使用一個臨時表。 “Using filesort” 這意味著mysql會對結果使用一個外部索引排序,而不是按索引次序從表裡讀取行。mysql有兩種檔案排序演算法,這兩種排序方式都可以在記憶體或者磁碟上完成,explain不會告訴你mysql將使用哪一種檔案排序,也不會告訴你排序會在記憶體裡還是磁碟上完成。 “Range checked for each record(index map: N)” 這個意味著沒有好用的索引,新的索引將在聯接的每一行上重新估算,N是顯示在possible_keys列中索引的點陣圖,並且是冗餘的
部落格參考:https://www.cnblogs.com/majj/p/9196025.html