数据库索引,真的越建越好吗?(下)

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 索引是提高关系型数据库查询性能的利器,但其并非银弹,必须精通其原理,才能发挥奇效。

MySQL如何基于成本制定执行计划

现在,我要用下面的SQL

8.png

执行计划是全表扫描。但只要把create_time条件中的5点改为6点就变为走索引了,并且走的是create_time索引而不是name_score联合索引:

9.png

该实验可以得到如下结论:

  • MySQL选择索引,并非按照WHERE条件中列的顺序
  • 即便列有索引,甚至有多个可能的索引方案,MySQL也可能根本不走索引

因为MySQL是根据成本判断的。虽然表的统计信息不完全准确,但足够用于策略的判断。


不过,有时会因为统计信息的不准确或成本估算问题,实际开销会和MySQL统计出来的差距较大,导致MySQL选择错误的索引或是直接全表扫描,这就需要人工干预,使用强制索引。

强制走name_score索引:

EXPLAIN 
SELECT * 
FROM person 
FORCE INDEX(name_score) 
WHERE NAME >'name84059' 
AND create_time>'2020-01-24 05:00:00' 

MySQL会根据成本选择执行计划,通过EXPLAIN可以知道优化器最终会选择怎样的执行计划,但MySQL如何制定执行计划始终是一个黑盒。

有没有什么办法可以了解各种执行计划的成本,以及MySQL做出选择的依据?


MySQL 5.6及之后,可以使用optimizer trace查看优化器生成执行计划的整个过程。有了这个功能,我们不仅可以了解优化器的选择过程,更可以了解每一个执行环节的成本,然后依靠这些信息进一步优化查询。

  • 打开optimizer_trace后
  • 再执行SQL
  • 就可以查询information_schema.OPTIMIZER_TRACE表查看执行计划了
  • 最后可以关闭optimizer_trace
SET optimizer_trace="enabled=on";
SELECT * FROM person WHERE NAME >'name84059' AND create_time>'2020-01-24 05:00:00';
SELECT * FROM information_schema.OPTIMIZER_TRACE;
SET optimizer_trace="enabled=off";

对于按照create_time>'2020-01-24 05:00:00’条件走全表扫描的SQL,来分析OPTIMIZER_TRACE的执行结果。


使用person_name_score_index对name84059<name条件进行索引扫描需扫描33918行,成本11872,所以未选择该方案

33918 = 查询二级索引的I/O成本和CPU成本 + 回表查询聚簇索引的I/O成本和CPU成本

image.png

使用person_create_time_index进行索引扫描需要扫描35606行,成本是12462,也是因为成本未选择该方案

image.png

最终选择全表扫描作为执行计划。全表扫描100147条记录的成本是10103,小于其他方案。

image.png

把SQL中的create_time条件从05:00改为06:00,再次分析OPTIMIZER_TRACE。这次执行计划选择的是走person_create_time_index索引。因为是查询更晚时间的数据,走person_create_time_index索引需要扫描的行数从35606减少到了27218。这次走这个索引的成本9526.6小于全表扫描的10103,更小于走name_score索引的30435:

image.png

考虑到索引的维护代价、空间占用和查询时回表的代价,不能认为索引越多越好。索引一定是按需创建的,并且要尽可能确保足够轻量。

一旦创建了多字段的联合索引,我们要考虑尽可能利用索引本身完成数据查询,减少回表。


不能认为建了索引就一定有效,对于后缀的匹配查询、查询中不包含联合索引的第一列、查询条件涉及函数计算等无法使用索引。

即使SQL本身符合索引使用条件,MySQL也会通过评估各种查询方式的代价,来决定是否走索引,走哪个索引。


尝试通过索引进行SQL性能优化时,请一定通过执行计划或实际的效果来确认索引是否能有效改善性能问题,否则增加了索引不但没解决性能问题,还增加了数据库增删改的负担。

对EXPLAIN结果困惑的,还可以利用optimizer_trace查看详细的执行计划,各个索引的成本是多少,看看到底怎么挑选出来的最终方案。


参考

https://dev.mysql.com/doc/internals/en/optimizer-tracing.html


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
17天前
|
数据库 索引
数据库索引的作用和优点缺点
数据库索引的作用和优点缺点
13 1
|
1月前
|
存储 搜索推荐 关系型数据库
深度探讨数据库索引的数据结构及优化策略
深度探讨数据库索引的数据结构及优化策略
|
3月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶-索引
摘要:MySQL基本概念、优缺点、索引结构与常见面试题、使用规则(最左前缀、索引失效、覆盖索引)、索引使用注意事项、索引设计原则。
249 2
|
3月前
|
数据库 索引 OceanBase
OceanBase数据库设置了二级索引,但查看执行计划,没有反应出来,这种情况是为什么呢?
OceanBase数据库设置了二级索引,但查看执行计划,没有反应出来,这种情况是为什么呢?【1月更文挑战第12天】【1月更文挑战第60篇】
78 2
|
1月前
|
存储 关系型数据库 MySQL
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
178 0
|
3月前
|
SQL 关系型数据库 MySQL
|
1月前
|
存储 缓存 负载均衡
数据库性能优化(查询优化、索引优化、负载均衡、硬件升级等方面)
数据库性能优化(查询优化、索引优化、负载均衡、硬件升级等方面)
|
1月前
|
存储 SQL 关系型数据库
【MySQL 数据库】6、一篇文章学习【索引知识】,提高大数据量的查询效率【文末送书】
【MySQL 数据库】6、一篇文章学习【索引知识】,提高大数据量的查询效率【文末送书】
59 0
|
2月前
|
存储 关系型数据库 数据库
数据库索引的原理,为什么要用 B+树,为什么不用二叉树?
数据库索引的原理,为什么要用 B+树,为什么不用二叉树?
|
2月前
|
存储 算法 关系型数据库
向量数据库的索引技术
【2月更文挑战第2天】向量数据库的索引技术
84 0

热门文章

最新文章