性能調優中對響應時間過長的優化,一上來就說加索引,朋友們,加了索引SQL不規范不走索引丁點用也沒有。
大家平時在開發過程中都避免不了使用數據庫索引,那么你了解數據庫索引么,接下來呢,我就簡單講一下什么是數據庫索引。
一、數據索引是干什么用的呢?
數據庫索引其實就是為了使查詢數據效率快。
二、數據庫索引有哪些呢?
- 聚集索引(主鍵索引):在數據庫里面,所有行數都會按照主鍵索引進行排序。
- 非聚集索引:就是給普通字段加上索引。
- 聯合索引:就是好幾個字段組成的索引,稱為聯合索引。
1
|
key
'idx_age_name_sex'
(
'age'
,
'name'
,
'sex'
)
|
聯合索引遵從最左前綴原則,什么意思呢,就比如說一張學生表里面的聯合索引如上面所示,那么下面A,B,C,D,E,F哪個會走索引呢?
1
2
3
4
|
A:select * from student where age =
16
and name =
'小張'
B:select * from student where name =
'小張'
and sex =
'男'
C:select * from student where name =
'小張'
and sex =
'男'
and age =
18
D:select * from student where age >
20
and name =
'小張'
<br>E:select * from student where age !=
15
and name =
'小張'
<br>F:select * from student where age =
15
and name !=
'小張'
|
A遵從最左匹配原則,age是在最左邊,所以A走索引;
B直接從name開始,沒有遵從最左匹配原則,所以不走索引;
C雖然從name開始,但是有索引最左邊的age,mysql內部會自動轉成where age = '18' and name = '小張' and sex = '男' 這種,所以還是遵從最左匹配原則;
D這個是因為age>20是范圍,范圍字段會結束索引對范圍后面索引字段的使用,所以只有走了age這個索引;
E這個雖然遵循最左匹配原則,但是不走索引,因為!= 不走索引;
F這個只走age索引,不走name索引,原因如上;
三、有哪些列子不走索引呢?
表student中兩個字段age,name加了索引
1
2
|
key
'idx_age'
(
'age'
),
key
'idx_name'
(
'name'
)
|
1.Like這種就是%在前面的不走索引,在后面的走索引
1
2
|
A:select * from student where
'name'
like
'王%'
B:select * from student where
'name'
like
'%小'
|
A不走索引,B走索引
2.用索引列進行計算的,不走索引
1
2
|
A:select * from student where age =
10
+
8
B:select * from student where age +
8
=
18
|
A走索引,B不走索引
3.對索引列用函數了,不走索引
1
2
|
A:select * from student where concat(
'name'
,
'哈'
) =
'王哈哈'
;
B:select * from student where name = concat(
'王哈'
,
'哈'
);
|
A不走索引,B走索引
4. 索引列用了!= 不走索引,如下:
1
|
select * from student where age !=
18
|
四、為什么索引用B+樹?
這個可以參考什么是B+樹
五、索引在磁盤上的存儲?
聚集索引和非聚集索引存儲的不相同,那么來說下都是怎么存儲的?
有一張學生表
create table `student` (
`id` int(11) not null auto_increment comment '主鍵id',
`name` varchar(50) not null default '' comment '學生姓名',
`age` int(11) not null default 0 comment '學生年齡',
primary key (`id`),
key `idx_age` (`age`),
key `idx_name` (`name`)
) ENGINE=InnoDB default charset=utf8 comment ='學生信息';
表中內容如下
id 為主鍵索引,name和age為非聚集索引
1.聚集索引在磁盤中的存儲
聚集索引葉子結點存儲是表里面的所有行數據;
每個數據頁在不同的磁盤上面;
如果要查找id=5的數據,那么先把磁盤0讀入內存,然后用二分法查找id=5的數在3和6之間,然后通過指針p1查找到磁盤2的地址,然后將磁盤2讀入內存中,用二分查找方式查找到id=5的數據。
2.非聚集索引在磁盤中的存儲
葉子結點存儲的是聚集索引鍵,而不存儲表里面所有的行數據,所以在查找的時候,只能查找到聚集索引鍵,再通過聚集索引去表里面查找到數據。
如果要查找到name = 小徐,首先將磁盤0加載到內存中,然后用二分查找的方法查到在指針p1所指的地址上,然后通過指針p1所指的地址可知道在磁盤2上面,然后通過二分查找法得知小徐id=4;
然后在根據id=4將磁盤0加載到內存中,然后通過二分查找的方法查到在指針p1所指的地址上,然后通過指針p1所指的地址可知道在磁盤2上面,然后通過id=4查找出鄭正行數據,就查找出name=小徐的數據了。