内容包括:
索引存储在内存中,为服务器存储引擎为了快速找到记录的一种数据结构。
为数据表添加索引:
ALTER TABLE table_name ADD INDEX index_name (column_list) //普通索引 ALTER TABLE table_name ADD UNIQUE (column_list) //唯一性索引,设置后,不允许插入重复值 ALTER TABLE table_name ADD PRIMARY KEY (column_list) //唯一索引,通常用于自增主键。
删除索引
DROP INDEX index_name ON talbe_name ALTER TABLE table_name DROP INDEX index_name ALTER TABLE table_name DROP PRIMARY KEY
查看索引
SHOW INDEX FROM tblname; SHOW KEYS FROM tblname;
缺点:
使用注意:
平衡多路查找树,一棵m阶的B树。
特性:
B树存在磁盘中,我们想要查找29,查找过程:
1. 根据根结点找到文件目录的根磁盘块1,将其中信息导入内存。 【磁盘IO操作一次】
2. 此时内存中有两个文件17,35和三个存储其他磁盘页面地址的数据。 比较:17<29<35,因此我们访问指针P2
3. 根据P2指针,我们定位到磁盘3,并将其信息导入内存。【磁盘IO操作2次】
4. 此时内存中有两个文件26,30和三个存储其他磁盘页面地址信息的指针,26<29<30,因此我们找到P2指针。
5. 根据P2指针,定位到磁盘8,将其中信息导入内存。【磁盘IO操作3次】
相对B树的不同特性:
单行查询时与B树相同
范围查询时,比如查找大于3小于8的数据,根据单行查找方式查找到3之后,通过链表直接遍历后面的元素。
索引分主索引和辅助索引
主索引在表创建后即存在。以主键为索引,叶子节点存储元素数据。
为主键外的字段添加的索引为辅助索引。以字段内容为索引,叶子节点存储元素对应主键。
MyISAM不同点在于叶子存储的不是元素数据,而是元素数据地址。实现索引与实际数据分离。
SQL语句使用不当时,将无法使用现存索引而去全表扫描。所以需要注意:索引列不能是表达式的一部分,也不能是函数的参数。
通过在查询SQL前加explain,查看是否有使用索引。
上图中,为timestamp字段添加了索引。 明显使用DATE()函数后,timestamp不使用索引,rows行数为总数据行数。
选择性指不重复的索引值和数据表的记录总数的比值。选择性最高时,即所有键不重复时选择性为1。
由上面对索引内部实现的描述我们得知,我们索引的字段越长时,所占内存也就越大。前缀索引意在保持较高选择性的情况下,取字段的前缀部分用于索引,降低内存使用率。
我对测试表中pdl字段及前缀部分的选择性进行观测如下:
如图,前缀为9时选择性已经较高,再增加时,没有明显提升。这时,如果pdl字段很长,就可以考虑使用pdl的前缀9个字符作为前缀索引。
alter table com_pdl_stat add key `left_pdl`(pdl(9));
注意:无法使用前缀索引做ORDER BY 和 GROUP BY,考虑业务场景做取舍。
很多时候我们为了查询方便,为很多列单独创建索引。但我们在使用where筛选时,却多使用AND,OR等条件。
当我为表的pdl,timestamp字段单独设置索引时,and查询为:
通过key标志知道此时仅使用了pdl字段的索引。filtered仅17.92.
这里的仅使用了pdl字段索引。(高性能提到5.0之后的版本会各自使用pdl和timestamp字段,然后SQL服务器对多个索引结果做相交(AND)或联合操作(OR)操作,通过extra可查询,但是我的5.7没有这种优化,不知道为什么~~)
如上,仅使用where条件的第一个字段索引 或者 服务器消耗CPU,内存等资源去做合并工作,都会影响查询性能。
这是有必要合并索引,创建pdl_time(pdl
, timestamp
)索引后同样的查询结果如下:
pdl_time索引被使用,filtered达到100%。
在创建多列索引时注意:
- 通常将选择性高的字段放在前面
- 多列字段的前缀也可以作为索引(例如(a,b)索引时,可以单独使用a索引,但不能单独使用b索引)
聚簇索引指的是一种数据组织结构。判断标准为:索引的叶子节点中,存储的是数据还是只想数据块的指针。如果是指向数据块指针,则为非聚簇索引。
索引类型依赖存储引擎,Innodb使用的是聚簇索引,MyISAM使用非聚簇索引
如图为Innodb存储引擎生成的主键索引结构。非叶子节点存储主键,叶子节点存储主键和行数据(还有事务ID和回滚指针)。
Innodb辅助索引图:
如图为Innodb存储引擎生成的辅助索引结构。叶子节点存储索引字段和对应的主键值,索引到主键值后,根据主键值再去主键索引中查找对应的数据。
非聚簇索引图:
非聚簇索引主键索引和辅助索引结构一致。
先确保服务响应慢时,不是一些偶然情况或者机器性能问题,确定响应慢源头是SQL操作。
// 查看是否开启了慢查询日志 show variables like '%slow_query_log'; // 开启 set global slow_query_log='ON'; // 执行show variables like '%slow_query_log'就有log_file地址 +---------------------+--------------------------------------------+ | Variable_name | Value | +---------------------+--------------------------------------------+ | slow_query_log | ON | | slow_query_log_file | /usr/local/mysql/data/TEST-slow.log | +---------------------+--------------------------------------------+ // 查看慢查询阈值 show variables like '%long_query_time%'; // 调整阈值 set global long_query_time = 1; // 关闭当前session再开启,执行一个超过1s的SQL时,将被记录在 `/usr/local/mysql/data/TEST-slow.log`里