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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 索引是提高关系型数据库查询性能的利器,但其并非银弹,必须精通其原理,才能发挥奇效。

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


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
20天前
|
数据库 索引
深入探索数据库索引技术:回表与索引下推解析
【10月更文挑战第15天】在数据库查询优化的领域中,回表和索引下推是两个核心概念,它们对于提高查询性能至关重要。本文将详细解释这两个术语,并探讨它们在数据库操作中的作用和影响。
43 3
|
20天前
|
数据库 索引
深入理解数据库索引技术:回表与索引下推详解
【10月更文挑战第23天】 在数据库查询性能优化中,索引的使用是提升查询效率的关键。然而,并非所有的索引都能直接加速查询。本文将深入探讨两个重要的数据库索引技术:回表和索引下推,解释它们的概念、工作原理以及对性能的影响。
41 3
|
6天前
|
数据库 索引
数据库索引
数据库索引 1、索引:建立在表一列或多列的辅助对象,目的是加快访问表的数据。 2、索引的优点: (1)、创建唯一性索引,可以确保数据的唯一性; (2)、大大加快数据检索速度; (3)、加速表与表之间的连接; (4)、在查询过程中,使用优化隐藏器,提高系统性能。 3、索引的缺点: (1)、创建和维护索引需要耗费时间,随数据量增加而增加; (2)、索引占用物理空间; (3)、对表的数据进行增删改时,索引需要动态维护,降低了数据的维护速度。
17 2
|
1月前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
61 3
Mysql(4)—数据库索引
|
16天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
82 1
|
10天前
|
存储 关系型数据库 数据库
Postgres数据库BRIN索引介绍
BRIN索引是PostgreSQL提供的一种高效、轻量级的索引类型,特别适用于大规模、顺序数据的范围查询。通过存储数据块的摘要信息,BRIN索引在降低存储和维护成本的同时,提供了良好的查询性能。然而,其适用场景有限,不适合随机数据分布或频繁更新的场景。在选择索引类型时,需根据数据特性和查询需求进行权衡。希望本文对你理解和使用PostgreSQL的BRIN索引有所帮助。
17 0
|
17天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
47 0
|
1月前
|
关系型数据库 MySQL 数据库
深入浅出MySQL索引优化:提升数据库性能的关键
在这个数据驱动的时代,数据库性能的优劣直接关系到应用的响应速度和用户体验。MySQL作为广泛使用的数据库之一,其索引优化是提升查询性能的关键。本文将带你一探MySQL索引的内部机制,分析索引的类型及其适用场景,并通过实际案例演示如何诊断和优化索引,以实现数据库性能的飞跃。
|
1月前
|
存储 SQL 数据库
深入理解数据库索引:提升查询性能的关键
数据库索引是优化查询性能的重要工具。本文将带你深入探索索引的内部结构和工作原理,揭示如何通过合理使用索引来加速数据库查询,同时避免常见的索引陷阱。
|
2月前
|
监控 关系型数据库 MySQL
如何优化MySQL数据库的索引以提升性能?
如何优化MySQL数据库的索引以提升性能?
121 0