mysql索引使用策略

简介: mysql索引使用策略

引语:

最近看了《高性能mysql》,虽然还没看完,但是觉得确实写得挺好的。索引部分看完还是对自己创建索引和了解
mysql的索引运行原理有了很大的帮助。做了些关于索引的笔记,遇到问题的时候可以回溯下参考下。

1.索引的优点:

要是对mysql索引的基本概念还不太清楚的话,可以看下我之前的两篇博客。
mysql聚簇索引和非聚簇索引,大白话btree和b+tree。

1.1 索引大大减少了服务器需要扫描行的数量
1.2 索引可以帮助服务器避免排序和临时表
1.3 索引可以随机I/O变为顺序I/O

2.使用索引的策略

2.1 独立的列

查询时索引列要是独立的列,指的是索引不能是表达式的一部分,也不能是函数的参数
错误例子:

1. select user_id from user where user_id + 1 = 7;  这里完全可以写成user_id = 6,这样索引才会生效  
2. select * ...where to_days(current_date)-to_days(date_col) <=10  

注:__如果把索引的列,像上面的例子中where后面的字段是加了索引的,但是因为对索引的列进行了操作(变成了user_id + 1这样的表达式),
或者是使用函数对索引列进行了操作。这样都会导致索引失效。__

2.2 前缀索引和索引选择性

2.2.1

当有一些需要被查询的列比较长的时候,我们可以创建前缀索引,就是这个列的前面某个长度的索引,比如alibabayushishidadao,我们建立前八位的索引,就是alibaba,用这个前缀来搜索对应的列.但是这里有一个问题就是,怎么来确定这个前缀索引的长度呢?
这个提一个概念叫做,__索引选择性__.索引选择性是指不重复的索引和数据记录总数T的比值.范围是1/T~1之间.索引的选择性越高,则查询效率越高,因为这代表着索引覆盖的不重复数据越多,能在查询的时候过滤掉更多的行.索引的选择性是1,那么这个索引的性能极高.
因此我们需要设置一个合理的前缀索引长度让索引选择率更高.
例子:

select count(distinct left(phone, 3))/count(*) as prefix3,  
count(distinct left(phone, 5))/count(*) as prefix5,  
count(distinct left(phone, 7))/count(*) as prefix7  
from table;

咱们假设是对phone这个字段进行前缀索引化,通过上面的count可以计算出哪个比率是最接近直接使用完整的phone的索引选择率。
这样咱们就可以对索引改为前缀索引,从而减少索引的长度,提升查询效率。

2.2.2 创建前缀索引:

alter table user add key (user_name(7)) 数字就是前缀索引的长度

2.2.3 前缀索引的缺点:

1.前缀索引因为不是列的全部长度,所以无法进行group by和 order by
2.同时也是因为不是列的全部长度,所以无法达到覆盖索引

2.2.4 注:前缀索引其他的的使用场景是针对较长的数据使用唯一id,或者有时候需要使用到后缀索引(当然mysql是不支持的,但是我们在存储数据的时候将数据翻转过来储存)

2.3 多列索引

如果发现explain中有出现type=index_merge,那么就得考虑索引创建的合理性的问题了。
这种索引合并通常会消耗大量的cpu和内存资源,更重要的是优化器不会把这些计算到查询的成本中,优化器只关心随机页面读取的数据量有多少。

2.4 选择合适的索引顺序

索引的顺序没有什么固定的法则,要根据实际使用情况来创建。
不过一般情况,咱们将使用频率高,索引选择率高的字段放在前面,涉及到范围查询和使用频次低的放在后面。

3.5聚簇索引

3.5.1

主键最好是自增的id,这样每次有新数据进来的时候对于聚簇索引的数据只需要在最后的一列新增数据即可,即使当前的数据页满了的话,也只需要从新的一页开始新增数据.如果是uuid等没有顺序的主键的,话因为插入的数据在innodb中是按顺序来的,假设插入的uui的主键小于之前的主键,那么之前的的数据都会被移动,让新数据插入,遇到数据页满了的情况更是要消耗更多的资源去处理这样的情况.会不停的有页分裂的情况产生,不停的页分裂就会导致有碎片产生,那么就会比普通的自增主键占用更多的空间.

3.5.2

自增主键的缺点:在有并发的情况下,可能会导致资源的竞争,因为自增id的上界是每个线程都会去竞争的,所有的插入都是需要获取到最新的最大的自增id,而并发会让这个上界不停的在变化中.

3.5.3

mysql不能再索引中执行like操作,如果是最左前缀的like比较是可以走索引的,因为会被转换为简单的比较操作.但是如果是通配符开头的like"%xxx%"这样的范围查询是不走索引的.因为搜索引擎无法拿通配符和具体的索引去作比较.

tips:select sum(description = 3),sum(category_type = 2) from shop_page_field; 这样可以统计改字段属于某个值的数据有多少条,相较于count这个好像写起来更方便,但是性能比较如何,那就不得而知啦.

4.5.覆盖索引

4.5.1 覆盖索引的好处:

1.覆盖索引数据的条目比总的数据量要小,查询的速度会更快
2.对于innod来说直接从索引上获取了数据就不需要在走聚簇索引,不需要进行二次查询

4.6.未使用的索引

在服务器中打开userstates(默认是关闭的),然后让服务器运行一段时间。再通过查询INFORMATION_SCHEMAINDEX.STATISTCS就能查询到某个索引的使用率。如果某个索引没有被使用的话可以删除掉。

4.7 索引和锁

innodb的锁的粒度是可以到行级,总共有行级锁和表级锁。这里行锁是必须加了索引才能达到,因为索引上保存了主键和索引和信息,
才能精准的锁到那一行数据。如果没有加上索引,进行update等操作的时候是会锁表的,这个要注意。

4.8 索引和排序

如果某个字段经常会用来排序,最好加上索引,通过explain的关键字可以看到extra字段里面会返回filesort(mysql叫做文件排序,虽然不一定会用到磁盘文件),
加上索引之后就不会显示这个filesort。
假设咱们有索引(A,B,C)
然后有查询语句,对象下面排序是否生效的情况

(1)select * from table where A = 'a' order by B, C;(索引生效)
(2)select * from table where A = 'a' order by B;(索引生效)
(3)select * from table where A = 'a' order by A, B;(索引生效)
(4)select * from table where A = 'a' order by C; (索引对A生效,对C排序没有生效)
(5)select * from table where A = 'a' order by B, D (不生效,引用了一个不再索引列的字段)
(6)select * from table where A > 'a' order by B, C(不生效,对于A是范围查询,索引失效)
(7)select * from table where A = 'a' and B in ('b1', 'b2') order by C (失效对于B in的情况也是范围查询,索引失效)

4.9 其他优化策略

当查询的内容是类似url的时候,使用btree效率会不那么高,因为url一般都比较长,索引搜索次数和效率并不好。
这个时候我们可以对url进行crc32或者crc64,计算出它的hash值存储起来.
但是crc32/crc64会产生碰撞,所以查询条件要带上原有的url;
select * from url_table where url_hash = "1342134234" and url = "http://www.baidu.com".
首先会根据url_hash去找到对应的url,可能有碰撞但是查询很快,然后再根据url的值去筛选,
这样查询起来性能就会很高.
这里url_hash还是使用的btree索引,只是用来过滤url会比对直接的长url会快很多.可以成为伪hash索引

注:crc64,fnv64()都需要mysql额外安装插件哦,不是mysql官方自带的。所以如果没有安装的话,咱们可以在程序中写入数据的时候进行MD5等类似操作保存一个hash值。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
存储 关系型数据库 MySQL
MySQL数据库索引的数据结构?
MySQL中默认使用B+tree索引,它是一种多路平衡搜索树,具有树高较低、检索速度快的特点。所有数据存储在叶子节点,非叶子节点仅作索引,且叶子节点形成双向链表,便于区间查询。
359 4
|
存储 关系型数据库 MySQL
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
|
缓存 关系型数据库 MySQL
降低MySQL高CPU使用率的优化策略。
通过上述方法不断地迭代改进,在实际操作中需要根据具体场景做出相对合理判断。每一步改进都需谨慎评估其变动可能导致其他方面问题,在做任何变动前建议先在测试环境验证其效果后再部署到生产环境中去。
463 6
|
缓存 关系型数据库 MySQL
在MySQL中处理高并发和负载峰值的关键技术与策略
采用上述策略和技术时,每个环节都要进行细致的规划和测试,确保数据库系统既能满足高并发的要求,又要保持足够的灵活性来应对各种突发的流量峰值。实施时,合理评估和测试改动对系统性能的影响,避免单一措施可能引起的连锁反应。持续的系统监控和分析将对维护系统稳定性和进行未来规划提供重要信息。
589 15
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
394 2
|
存储 关系型数据库 MySQL
MySQL覆盖索引解释
总之,覆盖索引就像是图书馆中那些使得搜索变得极为迅速和简单的工具,一旦正确使用,就会让你的数据库查询飞快而轻便。让数据检索就像是读者在图书目录中以最快速度找到所需信息一样简便。这样的效率和速度,让覆盖索引成为数据库优化师傅们手中的尚方宝剑,既能够提升性能,又能够保持系统的整洁高效。
460 9
|
机器学习/深度学习 关系型数据库 MySQL
对比MySQL全文索引与常规索引的互异性
现在,你或许明白了这两种索引的差异,但任何技术决策都不应仅仅基于理论之上。你可以创建你的数据库实验环境,尝试不同类型的索引,看看它们如何影响性能,感受它们真实的力量。只有这样,你才能熟悉它们,掌握什么时候使用全文索引,什么时候使用常规索引,以适应复杂多变的业务需求。
423 12
|
缓存 关系型数据库 MySQL
MySQL数据库性能调优:实用技术与策略
通过秉持以上的策略实施具体的优化措施,可以确保MySQL数据库的高效稳定运行。务必结合具体情况,动态调整优化策略,才能充分发挥数据库的性能潜力。
897 0
|
关系型数据库 MySQL 大数据
大数据新视界--大数据大厂之MySQL 数据库课程设计:MySQL 数据库 SQL 语句调优的进阶策略与实际案例(2-2)
本文延续前篇,深入探讨 MySQL 数据库 SQL 语句调优进阶策略。包括优化索引使用,介绍多种索引类型及避免索引失效等;调整数据库参数,如缓冲池、连接数和日志参数;还有分区表、垂直拆分等其他优化方法。通过实际案例分析展示调优效果。回顾与数据库课程设计相关文章,强调全面认识 MySQL 数据库重要性。为读者提供综合调优指导,确保数据库高效运行。

推荐镜像

更多