就是數據庫存儲數據的技術,能夠類比成發動機引擎,不一樣的引擎性能各不相同mysql
最多見的兩個存儲引擎是innodb和myisam,區別以下:算法
一、innodbsql
--一、(默認版本是5.5及以上)數據庫
--二、支持事務服務器
--三、不支持全文索引數據結構
--四、索引和數據在同一文件中,.ibdide
表的結構是在.frm文件中函數
二、myisam工具
--一、(默認版本5.5如下,主要5.3用的人最多)性能
--二、不支持事務
--三、支持全文索引
--四、.frm:表結構
.MYD:表數據
.MYI:表索引
三、memory(不經常使用)
ps:innodb不支持全文索引
國內廣泛用的全文索引 sphinx(斯芬克斯)
至關於新華字典的目錄,咱們能夠把索引理解成一個特殊的文件,
若是沒有這個文件,查詢是從前日後查找數據的,
若是有這個文件,會按照一種特殊的數據結構(二叉樹)查找數據
加快查詢的數據
一、主鍵索引:加快查詢 + 不能重複 + 不能爲空 primary key
二、惟一索引:加快查詢 + 不能重複 unique(列名)
聯合惟一索引:加快查詢 + 不能重複 unique(列名1,列名2,..)
三、普通索引:加快查詢 index(列名)
一、建表時建立
create table t1( # 主鍵的建立 id int auto_increment primary key, name varchar(32) not null default '', age int not null default 0, num int not null default 0, # 聯合惟一索引的建立 unique uni_name_num (name,age), # 普通索引的建立 index ix_age (age) ).engine=innodb charset=utf8;
二、表存在後建立
# 主鍵索引的建立 alter table t1 change id id int auto_increment primary key # 惟一索引的建立 create unique index ix_name on t1(name) create unique index ix_name_age on t1(name,age) # 普通索引的建立 create index ix_age on t1(age)
# 若是主鍵是自增的,則沒法刪除,要先取消自增再刪除 alter table t1 change id id int; alter table t1 drop primary key; # 刪除惟一索引和普通索引同樣 drop index ix_name on t1;
優勢:
查詢數據速度快
缺點:
版本5.3如下:
刪除和修改數據的速度會變得很慢,會重構索引
版本5.5以上:
刪除和修改數據的速度不是特別慢
數據庫表中添加索引後確實會讓查詢速度起飛,但前提必須是正確的使用索引
來查詢,若是以錯誤的方式使用,則即便創建索引也不會生效
錯誤索引案例
# -like '%xx' select * from t1 where name like '%cn%'; # -使用函數 select * from t1 where reverse(name) = 'xxx'; # -order by select email from t1 order by name desc; # 當根據索引排序時,選擇的映射若是不是索引,則不走索引 # 特別的:若是對主鍵排序,則仍是走索引 select * from t1 order by id;
explain 工具
查看sql語句是否用得上索引,或者查看sql執行效率的工具
給執行的sql語句出一個報告,經過此報告來判斷sql語句的
執行效率和效果(不必定都按結果上來)
SQL語句的規則
一、不建議使用like進行搜索
二、不建議使用函數
三、組合索引最左前綴
若是組合索引爲:(name,email)
where name and email --使用索引
where name --使用索引
where email --不適用索引
explain查詢以後參數的含義(瞭解)
id 查詢順序標識 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 tb1; 特別的:若是有limit限制,則找到以後就不在繼續向下掃描 select * from tb1 where email = 'xxxx@live.com' select * from tb1 where email = 'xxxx@live.com' limit 1; 雖然上述兩個語句都會進行全表掃描,第二句使用了limit,則找到一個後就再也不繼續掃描。 INDEX 全索引掃描,對索引從頭至尾找一遍 select nid from tb1; RANGE 對索引列進行範圍查找 select * from tb1 where name < 'xxx'; PS: between and in > >= < <= 操做 注意:!= 和 > 符號 REF 根據索引查找一個或多個值 select * from tb1 where name = 'xxx'; CONST 常量 表最多有一個匹配行,由於僅有一行,在這行的列值可被優化器剩餘部分認爲是常數,const表很快,由於它們只讀取一次。 select nid from tb1 where nid = 2 ; SYSTEM 系統 表僅有一行(=系統表)。這是const聯接類型的一個特例。 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將使用哪種文件排序,也不會告訴你排序會在內存裏仍是磁盤上完成。