当前位置: 首页 > 科技观察

MySQL索引使用监控技巧详解,值得收藏

时间:2023-03-15 10:14:58 科技观察

在关系型数据库中,索引是一种独立的、物理的存储结构,用于对数据库表中一个或多个列的值进行排序。它是表中一个或多个列中的值的集合,以及相应的逻辑指针列表,这些指针指向表中物理标识这些值的数据页。mysql支持hash和btree索引。innodb和myisam只支持btree索引,而内存和堆存储引擎可以支持hash和btree索引1、查看当前索引使用情况我们可以通过如下语句查询当前索引使用情况:Handler_read_first表示读取索引头的次数,如果这个值高,说明全索引扫描次数多。handler_read_key表示索引被使用的次数。如果我们增加一个新的索引,我们可以检查Handler_read_key是否增加了。如果有增加,说明SQL使用了索引。handler_read_next代表读取后面的索引,通常发生范围扫描。handler_read_prev代表读取索引的上列,一般出现在ORDERBY...DESC中。handler_read_rnd表示读取固定位置的行。如果这个值很高,说明大量的结果集被排序,进行了全表扫描,关联查询没有使用合适的KEY。handler_read_rnd_next表示表扫描很多,查询性能低。其实更多的应用场景是在索引工作的时候,Handler_read_key的值会很高,这个值代表一行读取索引值的次数,很低的值表示通过添加索引不高,因为索引不经常使用。Handler_read_rnd_next的高值意味着查询运行效率低下,应该通过建立索引来补救。该值的含义是请求读取数据文件中下一行的次数。如果正在进行大量的表扫描,并且Handler_read_rnd_next的值很高,通常说明表索引不正确或者写入的查询没有使用索引2.检查索引是否用于SELECTobject_type,object_schema,object_name,index_name,count_star,count_read,COUNT_FETCHFROMPERFORMANCE_SCHEMA.table_io_waits_summary_by_index_usage;如果read和fetch的次数为0,则没有被使用过。3、查看使用了哪些索引来解释相关的sql,查看type表示查询中使用了哪种索引类型+-----+--------+--------+-----+--------+--------+--------+------+|ALL|index|range|ref|eq_ref|常量|系统|空|+-----+------+------+-----+------+------+--------+------+从最好到最差:system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL系统表只有一条记录in,一般只出现在系统表中。const表示可以通过索引查询来查询。一般对应的索引列是primarykey或者在uniquewhere语句中指定一个常量。因为只匹配一行数据,MYSQL可以把这个查询优化为一个常量,所以速度很快。eq_ref唯一索引扫描。这种类型通常出现在多表的连接查询中。对于上一张表连接的每一个对应的列,当前表对应的列都有一个唯一索引,最多只有一行数据与之匹配。ref非唯一索引扫描。同上,但是当前表对应的列没有唯一索引,可能有多行数据匹配。这种类型通常出现在多表连接查询中,用于非唯一或非主键索引,或者用于使用最左前缀规则索引的查询。范围索引的范围查询。查询一系列索引键的值。index全文索引扫描。基本上和all一样,都是扫描全文,但是查询的字段是包含在索引中的,所以不需要读取表中的数据,只需要读取索引树中的字段即可。全部全文扫描。不使用索引并且效率最低。顺便说几个优化点:(1)优化insert语句:尽量使用insertintotestvalues(),(),(),()...如果插入多行来自不同客户,可以使用插入延迟语句以获得更高的速度,延迟的意思是让插入语句立即执行,实际上是将数据放在内存队列中,并没有真正写入磁盘,这比单独插入每个语句要快得多;low_priority恰好相反,在所有其他用户对表进行读写后插入。将索引文件和数据文件存放在不同的磁盘上(使用建表语句)如果要批量插入,可以增加bulk_insert_buffer_size变量值的方法来提高速度,但只用于MyISAM表。从文本文件加载表时,使用Loaddatafile通常比使用insert快20倍(2)优化groupby语句:默认情况下,mysql会对所有groupby字段进行排序,类似于orderby。如果查询包含groupby,但用户希望避免消费排序后的结果,可以指定orderbynull来禁用排序。(3)优化orderby语句:在某些情况下,mysql可以使用索引来满足orderby子句,所以不需要额外的排序。where条件和orderby使用同一个索引,orderby的顺序和索引的顺序相同,orderby的字段是升序或者降序。(4)优化嵌套查询:mysql4.1开始支持子查询,但在某些情况下,子查询可以用更高效的join代替,尤其是join的被动表要建索引的时候,因为mysql没有临时表需要在内存中创建以完成这个逻辑上的两步查询。最后一点:一张表最多可以有16个索引,最大索引长度为256字节。索引一般不会显着影响插入性能(大量小数据除外),因为索引的时间开销为O(1)或O(logN)。但是,索引太多也不好。毕竟更新等操作需要维护索引。