mysql索引使用策略

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 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值。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
196 66
|
15天前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
117 9
|
20天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
59 18
|
12天前
|
存储 Oracle 关系型数据库
索引在手,查询无忧:MySQL索引简介
MySQL 是一款广泛使用的关系型数据库管理系统,在2024年5月的DB-Engines排名中得分1084,仅次于Oracle。本文介绍MySQL索引的工作原理和类型,包括B+Tree、Hash、Full-text索引,以及主键、唯一、普通索引等,帮助开发者优化查询性能。索引类似于图书馆的分类系统,能快速定位数据行,极大提高检索效率。
45 8
|
19天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
22 7
|
18天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化与慢查询优化:原理与实践
通过本文的介绍,希望您能够深入理解MySQL索引优化与慢查询优化的原理和实践方法,并在实际项目中灵活运用这些技术,提升数据库的整体性能。
50 5
|
22天前
|
存储 关系型数据库 MySQL
Mysql索引:深入理解InnoDb聚集索引与MyisAm非聚集索引
通过本文的介绍,希望您能深入理解InnoDB聚集索引与MyISAM非聚集索引的概念、结构和应用场景,从而在实际工作中灵活运用这些知识,优化数据库性能。
93 7
|
20天前
|
缓存 NoSQL 关系型数据库
MySQL战记:Count( *)实现之谜与计数策略的选择
本文深入探讨了MySQL中`count(*)`的不同实现方式,特别是MyISAM和InnoDB引擎的区别,以及各种计数方法的性能比较。同时,文章分析了使用缓存系统(如Redis)与数据库保存计数的优劣,并强调了在高并发场景下保持数据一致性的挑战。
MySQL战记:Count( *)实现之谜与计数策略的选择
|
7天前
|
存储 关系型数据库 MySQL
【MYSQL】 ——索引(B树B+树)、设计栈
索引的特点,使用场景,操作,底层结构,B树B+树,MYSQL设计栈
|
2月前
|
SQL 关系型数据库 MySQL
PHP与MySQL的高效协同开发策略####
本文深入探讨了PHP与MySQL在Web开发中的协同工作机制,通过优化配置、最佳实践和高级技巧,展示了如何提升数据库交互性能,确保数据安全,并促进代码可维护性。我们将从环境搭建讲起,逐步深入到查询优化、事务管理、安全防护及性能调优等核心环节,为开发者提供一套实战驱动的解决方案框架。 ####