mysql數據庫邏輯分層結構:
InnoDB: 事務優先(適合高併發操作,行鎖)
MyISAM: 性能優先 (表鎖)
編寫過程:
select distinct … from … join … on … where … group by … having … order by … limit …
解析過程:
from … join … on … where … group by … having …select distinct … order by … limit …
索引:index相當於書的目錄,是幫組數據庫高效獲取數據的數據結構。
索引的弊端:
- 索引本身很大,可以存放在內存、硬盤中;
- 索引不是所有情況均使用:a、 少量數據;b、頻繁更新的字段;c、很少使用的字段
- 索引會降低增刪改的效率
索引的優勢:
- 提高查詢效率(降低IO使用率)
- 降低CPU使用率
索引分類:
- 單值索引:單列:age ,一個表可以多個單值索引;
- 唯一索引:列值不能重複,例如ID,可以是null
- 複合索引:多個列構成的索引
- 主鍵索引:不能重複,不能是null
添加索引:
alter table employee add index idx_name_managerId(name, managerId);
alter table employee add unique index idx_name(name);
刪除索引:
drop index idx_name on employee;
查看索引:
show index from employee;
SQL性能問題:
- 分析SQL的執行計劃: explain, 可以模擬SQL優化器執行SQL語句;
- SQL查詢優化會干擾我們的優化;
-
id: 編號
id字段相同:從上往下順序執行;
Id值不同:Id值越大越優先查詢(本質:在嵌套子查詢時,先查內存,再查外層); -
select_type: 查詢類型
PRIMARY: 包含子查詢SQL中的主查詢(最外層)
SUBQUERY: 包含子查詢SQL中的子查詢(非最外層)
SIMPLE: 簡單查詢(不包含子查詢,union的查詢)
DERIVED: 衍生查詢(使用到了臨時表)
a、在from子查詢中只有一張表
b、在from子查詢中,如果有table1 union table2 ,則table1就是derived,table2就是union
UNION: 上例;
UNION RESULT: 告知開發人員,哪些表之間存在union查詢
-
table: 表
-
type: 索引類型
system > const > eq_ref > ref > range > index > all;越往左,性能越高;
a、system : 只有一條數據的系統表或者衍生表只有一條數據的主查詢;
b、const: 僅僅能查到一條數據的SQL,用於Primary key或unique 索引(類型與索引類型有關)
c、eq_ref: 唯一性索引,對於每個索引鍵的查詢,返回匹配唯一行數據(有且只有1個,不能有多個,也不能有0個);
d、ref: 非唯一性索引,對於每個索引鍵的查詢,返回匹配的所有行
e、range: 檢索指定範圍的行,where後面是一個範圍查詢(between,in,> < >= )
f、index : 查詢全部索引中的數據:tname是索引列,只需掃描索引表,不需要掃描表中的所有數據;
g、all : 查詢全部表中的數據: tcdesc不是索引,需要全表掃描,即需要掃描表中的所有數據
-
possible_keys: 預測可能用到的索引
-
key: 實際使用的索引
-
key_len :實際使用索引的長度
-
ref: 表之間的引用;指明當前表所參照的字段
select … where a.c = b.x ; (其中b.x可以是常量,const)
-
rows : 通過索引優化查詢到的數據個數
-
Extra: 額外的信息
a、using filesort: 性能消耗大,需要額外的一次排序(查詢),一般用於order by語句中explain select * from courses where class = ‘Math’ order by class; – 不會有 Using filesort
explain select * from courses where class = ‘Math’ order by age; – 有 Using filesort
排序:排序的前提是先查詢,第二個語句在對age進行排序前由於沒有查詢過,必須先查詢一次,所以性能消耗大,需要額外一次排序。
對於單索引,如果排序和查找是同一個字段,則不會出現using filesort;如果排序和查找不是同一個字段,那麼就會出現using filesort。
複合索引:不能跨列(最左匹配原因)
建立一個聯合索引:
alter table courses add index idx_class_student_age(class,student,age);explain select * from courses where class = ‘Math’ order by student; – 不會有 Using filesort
explain select * from courses where class = ‘Math’ order by age; – 有 Using filesort
explain select * from courses where student = ‘B’ order by age; – 有 Using filesort
where和order by按照聯合索引的順序使用。b、using temporary: 性能損耗大,用到了臨時表,一般用於group by語句中
explain select class, age from courses where class in (‘Java’,‘Math’) and age = 24 group by class, age; – 沒有Using temporaryexplain select student from courses where class in (‘Java’,‘Math’) and age = 24 group by student; – 有Using temporary
如何避免:查詢哪些列,就根據哪些列進行group by。
c、using index: 性能提升,索引覆蓋
原因:不讀取原文件,只從索引文件中獲取數據,只要查詢的列全部都在索引中,就是索引覆蓋using index。
alter table courses add index idx_class_student_age(class,student,age);
下面3個查詢語句都用到了索引:
explain select class,age from courses ;
explain select student ,age from courses ;
explain select age from courses ;如果用到了索引覆蓋(using index)時,會對possible_keys和key造成影響;
1、如果沒有where,則索引只出現在key中;
2、如果有where,則索引出現在key和possible_keys中。c、using where: 需要回表查詢
假設age是索引列,但查詢語句select age,name from … where age = …;explain select class, age from courses where age = 24; – age需要會原表查詢
d、Impossible WHERE: where 字段永遠爲false
小結:
- Using index不讀數據文件,只從索引文件獲取數據
- Using where過濾元組和是否讀取數據文件或索引文件沒有關係;
- where 和order by 拼起來不要跨列使用
早前的MySQL版本in會導致索引失效,之後的版本in不會導致索引失效!!!!