mysql索引及优化

1 索引简介

1.1 索引定义

索引是帮助MySQL高效获取数据的数据结构。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。 一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往是存储在磁盘上的文件中的(可能存储在单独的索引文件中,也可能和数据一起存储在数据文件中)。
索引的优点:
可以提高数据检索的效率,降低数据库的IO成本,类似于书的目录;
通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗。

索引的缺点:
索引会占据磁盘空间;
索引虽然会提高查询效率,但是会降低更新表的效率。比如每次对表进行增删改操作,MySQL不仅要保存数据,还有保存或者更新对应的索引文件。

索引是一种特殊的文件,它们包含着对数据表里所有记录的引用指针。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。

(一)MySQL索引的类型

普通索引、唯一索引、主键索引、全文索引、组合索引

普通索引:这是最基本的索引,它没有任何限制,MyIASM中默认的BTREE类型的索引,也是我们大多数情况下用到的索引。

唯一索引:与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值(注意和主键不同)。

主键索引:它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引。

全文索引:MySQL从3.23.23版开始支持全文索引和全文检索,FULLTEXT索引仅可用于MyISAM表;他们可以从CHAR、VARCHAR或TEXT列中作为CREATE TABLE语句的一部分被创建,或是随后使用ALTER TABLE 或CREATE INDEX被添加。对于较大的数据集,将你的资料输入一个没有FULLTEXT索引的表中,然后创建索引,其速度比把资料输入现有FULLTEXT索引的速度更为快。不过切记对于大容量的数据表,生成全文索引是一个非常消耗时间非常消耗硬盘空间的做法。

组合索引:一个组合索引包含两个或两个以上的列。

(二)使用索引的优点

 1.可以通过建立唯一索引或者主键索引,保证数据库表中每一行数据的唯一性.

 2.建立索引可以大大提高检索的数据,以及减少表的检索行数 。

 3.在表连接的连接条件中包含索引可以加速表与表直接的相连。

 4.在分组和排序字句进行数据检索,可以减少查询时间中分组和排序时所消耗的时间(数据库的记录会重新排序) 。

 5.建立索引,在查询中使用索引可以提高性能。

(四)使用索引的缺点

 1.在创建索引和维护索引会耗费时间,随着数据量的增加而增加 。

 2.索引文件会占用物理空间,除了数据表需要占用物理空间之外,每一个索引还会占用一定的物理空间 。

 3.当对表的数据进行 INSERT,UPDATE,DELETE 的时候,索引也要动态的维护,这样就会降低数据的维护速度。

(五)使用索引需要注意的地方

 在建立索引的时候应该考虑索引应该建立在数据库表中的某些列上面,哪一些索引需要建立,哪一些所以是多余的.

一般来说,

 1.在经常需要搜索的列上,可以加快索引的速度

 2.主键列上可以确保列的唯一性

 3.在表与表的连接条件上加上索引,可以加快连接查询的速度

 4.在经常需要排序(order by),分组(group by)和distinct列上加索引,可以加快排序查询的时间

 5.MySQL只对以下操作符才使用索引:<,<=,=,>,>=,between,in,以及某些时候的like(不以通配符%或_开头的情形),所以对这些字段建立索引

 6.like语句,如果对xx字段建立了一个索引.当查询的时候的语句是 xx lick '%ABC%' 那么这个索引将不起作用.而xx lick 'ABC%' 那么这个语句将使用到索引

 7.索引不会包含NULL列,如果列中包含NULL值都将不会被包含在索引中,复合索引中如果有一列含有NULL值那么这个组合索引都将失效,一般需要给默认值0或者空字符串

 8.使用短索引,如果你的一个字段是Char(32)或者int(32),在创建索引的时候指定前缀长度,比如前10个字符(前提是多数值是唯一的)那么短索引可以提高查询速度,并且可以减少磁盘的空间,也可以减少I/0操作. (如果是字段类型是BLOB和TEXT类型,必须指定索引长度)

 9.不要在列上进行运算,这样会使得mysql索引失效,也会进行全表扫描

 10.选择越小的数据类型越好,因为越小的数据类型通常在磁盘,内存,cpu,缓存中占用的空间很少,处理起来更快。

 11.理论上每张表里面最多可创建16个索引,不过除非是数据量真的很多,否则过多的使用索引也不是那么好玩的。

(六)什么情况下不创建索引

 1.查询中很少使用到的列不应该创建索引,如果建立了索引反而会降低mysql的性能和增大物理空间的需求.

 2.很少数据的列也不应该建立索引,比如一个性别字段0或者1,在查询中,结果集数据占的比例比较大,mysql需要扫描的行数很多,增加索引,并不能提高效率 .

 3.定义为text,image,bit数据类型的列不应该增加索引.

 4.当表的修改(UPDATE,INSERT,DELETE)操作远远大于检索(SELECT)操作时不应该创建索引,这两个操作是互斥的关系.

1.2 索引的数据结构

1.2.1 Hash表

Hash表,在Java中的HashMap,TreeMap就是Hash表结构,以键值对的方式存储数据。我们使用Hash表存储表数据Key可以存储索引列,Value可以存储行记录或者行磁盘地址。Hash表在等值查询时效率很高,时间复杂度为O(1);但是不支持范围快速查找,范围查找时还是只能通过扫描全表方式。
显然这种并不适合作为经常需要查找和范围查找的数据库索引使用。

1.2.2 二叉查找树

每个节点最多有2个分叉,左子树和右子树数据顺序左小右大。
这个特点就是为了保证每次查找都可以这折半而减少IO次数,但是二叉树就很考验第一个根节点的取值,因为很容易在这个特点下出现我们并发想发生的情况“树不分叉了”,这就很难受很不稳定。
在这里插入图片描述

显然会出现上图这种不稳定的情况,我们在选择设计上必须要避免。

1.2.3 平衡二叉树

平衡二叉树是采用二分法思维,平衡二叉查找树除了具备二叉树的特点,最主要的特征是树的左右两个子树的层级最多相差1。在插入删除数据时通过左旋/右旋操作保持二叉树的平衡,不会出现左子树很高、右子树很矮的情况。
使用平衡二叉查找树查询的性能接近于二分查找法,时间复杂度是 O(log2n)。查询id=6,只需要两次IO。
在这里插入图片描述

就这个特点来看,可能各位会觉得这就很好,可以达到二叉树的理想的情况了。然而依然存在一些问题:
时间复杂度和树高相关。树有多高就需要检索多少次,每个节点的读取,都对应一次磁盘IO操作。树的高度就等于每次查询数据时磁盘IO操作的次数。磁盘每次寻道时间为10ms,在表数据量大时,查询性能就会很差。(1百万的数据量,log2n约等于20次磁盘IO,时间20*10=0.2s)
平衡二叉树不支持范围查询快速查找,范围查询时需要从根节点多次遍历,查询效率不高。

1.2.4 B树

MySQL的数据是存储在磁盘文件中的,查询处理数据时,需要先把磁盘中的数据加载到内存中,磁盘IO 操作非常耗时,所以我们优化的重点就是尽量减少磁盘 IO 操作。访问二叉树的每个节点就会发生一次IO,如果想要减少磁盘IO操作,就需要尽量降低树的高度。那如何降低树的高度呢? 假如key为bigint=8字节,每个节点有两个指针,每个指针为4个字节,一个节点占用的空间16个字节(8+42=16)。
因为在MySQL的InnoDB存储引擎一次IO会读取的一页(默认一页16K)的数据量,而二叉树一次IO有效数据量只有16字节,空间利用率极低。为了最大化利用一次IO空间,一个简单的想法是在每个节点存储多个元素,在每个节点尽可能多的存储数据。每个节点可以存储1000个索引(16k/16=1000),这样就将二叉树改造成了多叉树,通过增加树的叉树,将树从高瘦变为矮胖。构建1百万条数据,树的高度只需要2层就可以(1000
1000=1百万),也就是说只需要2次磁盘IO就可以查询到数据。磁盘IO次数变少了,查询数据的效率也就提高了。
这种数据结构我们称为B树,B树是一种多叉平衡查找树,如下图主要特点:
B树的节点中存储着多个元素,每个内节点有多个分叉。
节点中的元素包含键值和数据,节点中的键值从大到小排列。也就是说,在所有的节点都储存数据。
父节点当中的元素不会出现在子节点中。
所有的叶子结点都位于同一层,叶节点具有相同的深度,叶节点之间没有指针连接。
在这里插入图片描述

假如我们查询值等于10的数据。查询路径磁盘块1->磁盘块2->磁盘块6。
第一次磁盘IO:将磁盘块1加载到内存中,在内存中从头遍历比较,10<15,走15的左路节点P1,到磁盘寻址磁盘块2。
第二次磁盘IO:将磁盘块2加载到内存中,在内存中从头遍历比较,7<10,走7的右路节点P2,到磁盘中寻址定位到磁盘块6。
第三次磁盘IO:将磁盘块6加载到内存中,在内存中从头遍历比较,8<10,10=10,找到10,取出data。如果data存储的行记录,取出data,查询结束。如果存储的是磁盘地址,还需要根据磁盘地址到磁盘中取出数据,查询终止。

相比二叉平衡查找树,在整个查找过程中,虽然数据的比较次数并没有明显减少,但是磁盘IO次数会大大减少。同时,由于我们的比较是在内存中进行的,比较的耗时可以忽略不计。B树的高度一般2至3层就能满足大部分的应用场景,所以使用B树构建索引可以很好的提升查询的效率。
B树虽然看着很理想,但它依然存在可以优化的地方:
B树不支持范围查询的快速查找,你想想这么一个情况如果我们想要查找10和35之间的数据,查找到15之后,需要回到根节点重新遍历查找,需要从根节点进行多次遍历,查询效率有待提高;
如果data存储的是行记录,行的大小随着列数的增多,所占空间会变大。这时,一个页中可存储的数据量就会变少,树相应就会变高,磁盘IO次数就会变大。

1.2.5 B+树

B+树,作为B树的升级版,在B树基础上,MySQL在B树的基础上继续改造,使用B+树构建索引。B+树和B树最主要的区别在于非叶子节点是否存储数据的问题。
B树:非叶子节点和叶子节点都会存储数据。
B+树:只有叶子节点才会存储数据,非叶子节点至存储键值。叶子节点之间使用双向指针连接,最底层的叶子节点形成了一个双向有序链表。
在这里插入图片描述

B+树的最底层叶子节点包含了所有的索引项。从下图可以看到,B+树在查找数据的时候,由于数据都存放在最底层的叶子节点上,所以每次查找都需要检索到叶子节点才能查询到数据。所以在需要查询数据的情况下每次的磁盘的IO跟树高有直接的关系,但是从另一方面来说,由于数据都被放到了叶子节点,所以放索引的磁盘块锁存放的索引数量是会跟这增加的,所以相对于B树来说,B+树的树高理论上情况下是比B树要矮的。B+树一定是检索到叶子节点才能取到数据,而B树在索引中数据满足了当前查询语句所需要的全部数据,此时只需要找到索引即可立刻返回,不需要检索到最底层的叶子节点。

在这里插入图片描述

等值查询:
假如我们查询值等于9的数据。查询路径磁盘块1->磁盘块2->磁盘块6。
第一次磁盘IO:将磁盘块1加载到内存中,在内存中从头遍历比较,9<15,走15的左节点P1,到磁盘块2。
第二次磁盘IO:将磁盘块2加载到内存中,在内存中从头遍历比较,7<9<12,走7的右节点P2,到磁盘中寻址定位到磁盘块6。
第三次磁盘IO:将磁盘块6加载到内存中,在内存中从头遍历比较,在第三个索引中找到9,取出data,如果data存储的行记录,取出data,查询结束。如果存储的是磁盘地址,还需要根据磁盘地址到磁盘中取出数据,查询终止。(这里需要区分的是在InnoDB中Data存储的为行数据,而MyIsam中存储的是磁盘地址。)

在这里插入图片描述
范围查询:
假如我们想要查找9和26之间的数据。查找路径是磁盘块1->磁盘块2->磁盘块6->磁盘块7。
首先查找值等于9的数据,将值等于9的数据缓存到结果集。这一步和前面等值查询流程一样,发生了三次磁盘IO。
查找到15之后,底层的叶子节点是一个有序列表,我们从磁盘块6,键值9开始向后遍历筛选所有符合筛选条件的数据。
第四次磁盘IO:根据磁盘6后继指针到磁盘中寻址定位到磁盘块7,将磁盘7加载到内存中,在内存中从头遍历比较,9<25<26,9<26<=26,将data缓存到结果集。

主键具备唯一性(后面不会有<=26的数据),不需再向后查找,查询终止。将结果集返回给用户。
可以看到B+树可以保证等值和范围查询的快速查找,MySQL的索引就采用了B+树的数据结构。

2 MySQL的索引实现

2.1 MyISAM索引

2.1.1 主键索引

MyISAM的数据文件和索引文件是分开存储的,索引存储在.MYI的索引文件中,数据文件存储在.MYD的数据文件中。MyISAM使用B+树构建索引树时,叶子节点中存储的键值为索引列的值,数据为索引所在行的磁盘地址。
根据主键等值查询数据:select * from user where id = 28;

在这里插入图片描述

先在主键树中从根节点开始检索,将根节点加载到内存,比较28<75,走75的左节点P1。(1次磁盘IO)
将左子树节点加载到内存中,比较16<28<47,走47节点的左路P2。(1次磁盘IO)
检索到叶节点,将节点加载到内存中遍历,比较16<28,18<28,28=28。查找到值等于28的索引项。(1次磁盘IO)
从索引项中获取磁盘地址,然后到数据文件中获取对应整行记录(1次磁盘IO),将记录返给客户端。

磁盘IO次数:3次索引检索+记录数据检索。

在这里插入图片描述

根据主键范围查询数据:select * from user where id between 28 and 47;

先在主键树中从根节点开始检索,将根节点加载到内存,比较28<75,走75的左路P1。(1次磁盘IO)
将左子树节点加载到内存中,比较16<28<47,走47左路P2。(1次磁盘IO)
检索到叶节点,将节点加载到内存中遍历比较16<28,18<28,28=28<47。查找到值等于28的索引项。
根据磁盘地址从数据文件中获取行记录缓存到结果集中。(1次磁盘IO)
我们的查询语句时范围查找,需要向后遍历底层叶子链表,直至到达最后一个不满足筛选条件。向后遍历底层叶子链表,将下一个节点加载到内存中,遍历比较,28<47=47,根据磁盘地址从数据文件中获取行记录缓存到结果集中。(1次磁盘IO)
最后得到两条符合筛选条件,将查询结果集返给客户端。

磁盘IO次数:4次索引检索+记录数据检索

2.1.2 辅助索引

在MyISAM中,辅助索引和主键索引的结构是一样的,没有任何区别,叶子节点的数据存储的都是行记录的磁盘地址。只是主键索引的键值是唯一的,而辅助索引的键值可以重复。
查询数据时,由于辅助索引的键值不唯一,可能存在多个拥有相同的记录,所以即使是等值查询,也需要按照范围查询的方式在辅助索引树中检索数据。

2.2 InnoDB索引

在这里插入图片描述

2.2.1 主键索引(聚簇索引)

每个InnoDB表都有一个聚簇索引 ,聚簇索引使用B+树构建,叶子节点存储的数据是整行记录。一般情况下,聚簇索引等同于主键索引,当一个表没有创建主键索引时,InnoDB会自动创建一个ROWID字段来构建聚簇索引。InnoDB创建索引的具体规则如下:
在表上定义主键PRIMARY KEY,InnoDB将主键索引用作聚簇索引。
如果表没有定义主键,InnoDB会选择第一个不为NULL的唯一索引列用作聚簇索引。
如果以上两个都没有,InnoDB 会使用一个6 字节长整型的隐式字段 ROWID字段构建聚簇索引。该ROWID字段会在插入新行时自动递增。

除聚簇索引之外的所有索引都称为辅助索引。在中InnoDB,辅助索引中的叶子节点存储的数据是该行的主键值都。 在检索时,InnoDB使用此主键值在聚簇索引中搜索行记录。
InnoDB的数据和索引存储在一个.ibd的文件中。InnoDB的数据组织方式是聚簇索引。 主键索引的叶子节点会存储数据行,辅助索引只会存储主键值。
根据主键等值查询数据:select * from user_innodb where id = 28;
在这里插入图片描述

1.先在主键树中从根节点开始检索,将根节点加载到内存,比较28<75,走75的左路P1。(1次磁盘IO)
2.将左子树节点加载到内存中,比较16<28<47,走47节点的左路P2。(1次磁盘IO)
3.检索到叶节点,将节点加载到内存中遍历,比较16<28,18<28,28=28。查找到值等于28的索引项,直接可以获取整行数据。将该记录返回给客户端。(1次磁盘IO)磁盘IO数量:3次

根据主键范围查询数据:与等值查询前三部完全一致,会多一步步骤4。
4.需要向后遍历底层叶子链表,直至到达最后一个不满足筛选条件。向后遍历底层叶子链表,将下一个节点加载到内存中,遍历比较,28<47=47,然后将47对应的整行数据与28对应的整行数据一起返回。(1次磁盘IO)磁盘IO数量:4次。

2.2.2 辅助索引

在这里插入图片描述
聚簇索引之外的所有索引都称为辅助索引,InnoDB的辅助索引只会存储主键值而非磁盘地址。索引结果如下图。
在这里插入图片描述

底层叶子节点的按照(age,id)的顺序排序,先按照age列从小到大排序,age列相同时按照id列从小到大排序。
使用辅助索引需要检索两遍索引:首先检索辅助索引获得主键,然后使用主键到主索引中检索获得记录。

在这里插入图片描述
画图分析等值查询的情况:select * from t_user_innodb where age=19;

根据在辅助索引树中获取的主键id,到主键索引树检索数据的过程称为回表查询。
磁盘IO数:辅助索引3次+获取记录回表3次。

3 对比

了解了MySQL下两种索引的数据结构后,可以有以下结论:
InnoDB是聚簇索引,使用B+树作为索引结构,数据文件是和(主键)索引绑在一起的(表数据文件本身就是按B+Tree组织的一个索引结构),必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。
MyISAM是非聚集索引,也是使用B+树作为索引结构,索引和数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。
InnoDB推荐使用自增ID作为主键,自增ID可以保证每次插入时B+索引是从右边扩展的,可以避免B+树和频繁合并和分裂(对比使用UUID)。如果使用字符串主键和随机主键,会使得数据随机插入,效率比较差。

1、聚集索引

一个表中只能有一个,聚集索引的顺序与数据真实的物理存储顺序一致。查询速度快,聚集索引的叶子节点上是该行的所有数据 ,数据索引能加快范围查询(聚集索引的顺序和数据存放的逻辑顺序一致)。主键!=聚集索引。

注:mysql数据库innodb引擎里面,主键的确就是聚集索引。 但是myisam引擎里面主键也不是聚集索引

解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。

解释二: 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。

解释三:是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也即,索引包含了查询正在查找的所有数据

2、辅助索引(非聚集索引)

一个表中可以有多个,叶子节点存放的不是一整行数据,而是键值,叶子节点的索引行中还包含了一个’书签’,这个书签就是指向聚簇索引的一个指针,从而在聚簇索引树中找到一整行数据。

聚集索引与辅助索引的区别:叶子节点是否存放的为一整行数据

覆盖索引

指从辅助索引中就能获取到需要的记录,而不需要查找聚簇索引中的记录。使用覆盖索引的一个好处是因为辅助索引不包括一条记录的整行信息,所以数据量较聚集索引要少,可以减少大量io操作。

1)select * from table limit 9000000,100; -深分页,耗时比较长

2)select * from test where id >= (select id from test limit 9000000,1) limit 0,100 -利用主键聚簇索引

覆盖索引的好处:

    1 可以完全走索引获取数据,不用回表

    2 例如一些存储引擎如myisam 在内存中只缓存索引,而数据是依靠操作系统来缓存,因此访问数据要执行一次系统调用。这可能会导致严重的性能问题。

    3 innodb 的聚簇对innodb特别有用,如果普通索引能够覆盖查询,那么就不用再次去对主键做二次查询。

如果explain sql 返回的extra 列返回的是using index 就说明是覆盖索引

因为innodb二级索引存储的是索引列和主键值,所以我们查询在走二级索引的时候,如果查询的列只有二级索引列的话,再加1个主键列依然走的是覆盖索引,并且在二级索引查询就可以完全查到数据,从而不用在去主键索引上二次查询。

如果我有1个索引name .那么我select name from table 也会走覆盖索引

4 索引失效

优化器:当全表扫描速度比索引速度快时,mysql会使用全表扫描,此时索引失效

4.1 单索引时效的情况

1、like 以%开头,索引无效;当like前缀没有%,后缀有%时,索引有效。

1)explain select * from t_user where name like ‘name1%’ -走索引

2) explain select * from t_user where name like ‘%name1’ -索引失效

2、or语句前后没有同时使用索引。当or左右查询字段只有一个是索引,该索引失效,只有当or左右查询字段均为索引时,才会生效

1) explain select * from t_user where name = ‘name1’ or name=‘name2’ -走索引

2) explain select * from t_user where name = ‘name1’ or age=1 -索引失效(age无索引)

3、数据类型出现隐式转化。如varchar不加单引号的话可能会自动转换为int型,使索引无效,产生全表扫描。

1) explain select * from t_user where name = ‘name1’ -走索引

2) explain select * from t_user where name = 1 -不走索引

4、在索引列上使用 IS NULL 或 IS NOT NULL操作。索引不一定失效,MySQL中决定使不使用某个索引执行查询的依据很简单:就是成本够不够小

  1. explain select * from t_emp where ename is null -走索引

    原理参考文档:https://mp.weixin.qq.com/s/CEJFsDBizdl0SvugGX7UmQ

5、在索引字段上使用not,<>,!=。不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。

1) explain select * from t_user where name !=‘name1’ -不走索引

6、对索引字段进行计算操作、字段上使用函数

1) explain select * from t_user where left(name,2)=‘na’ -不走索引

7、查询的数量是大表的大部分,通常30%以上,也有其它因素的干扰

t_user :10条不同日期的记录

1)explain select * from t_user where create_time > ‘2021-11-01’ -不走索引

2)explain select * from t_user where create_time > ‘2021-11-06’ -不走索引

3)explain select * from t_user where create_time > ‘2021-11-07’ -走索引

优化:

1**)可以使用force index 强行走索引**

explain select * from t_user force index(idx_create_time) where create_time > ‘2021-11-01’ -走索引

问题:

为什么优化器查表为什么不走索引呢?
1)、优化器会根据检索比例、表大小、IO大小进行评估是否走索引,比如单次查询数据量过大

2)是否回表查询

  1. explain select * from t_user where id >1 -走索引,主键不用回表,IO次数减少,性能将提升不少

4.2 联合索引失效的情况

备注:name和sex为联合索引

1、联合索引所有成员均以and 出现时与顺序无关,都能生效

explain select * from t_student where sex = 0 and name ='张三 -走索引
2 、条件语句中出现or 则联合索引无效

explain select * from t_student where sex = 0 or name =‘张三’ -索引无效
3、条件语句中缺少排在第一位的索引字段,整个联合索引失效

explain select * from t_student where sex = 0 -不走索引

4、欲使联合索引要生效,排在第一位的索引为必须出现,位置不限

explain select * from t_student where age > 18 and name =‘name1’ -走索引
5、Mysql优化器选择

5 什么情况下不建议使用索引

1、唯一性差(特殊情况排除);
2、频繁更新的字段不用(更新索引消耗);
3、where中不用的字段;

6 索引优化

6.1 查询语句

//打开慢日志

set global slow_query_log=1;

//查询是否打开

SHOW VARIABLES like ‘slow_query_log’;

//修改日志存储方式,配置为文件和数据库两种

set global log_output=‘TABLE,FILE’;

//查看日志输出模式,

show variables like ‘log_output%’;

//是否把未走索引的sql记录到慢日志中

show variables like ‘log_queries_not_using_indexes%’;

//打开未走索引记录到慢日志开关0关闭1打开

set global log_queries_not_using_indexes =1;

//查询未使用索引的sql

SELECT * FROM mysql.slow_log ORDER BY start_time desc;

6.2 创建索引原则

1)尽量选择区分度高的列作为索引
2)为经常需要排序、分组和联合操作的字段建立索引
3)为常作为查询条件的字段建立索引
4)限制索引的数目
5)尽量的扩展索引,不要新建索引

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值