`
飞鱼德蒙
  • 浏览: 13142 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

为 MySQL 查询优化选择最佳索引

阅读更多

我们的许多用户、开发者和数据库管理员不断向我们的团队咨询有关 EverSQL 的索引推荐算法。

所以,我们决定写一些这方面的内容。

本教程不会详细介绍该算法的所有内部特性,而是要简单地说明索引最重要的方面。另外,也是最重要的,我们将通过基于一套规则而不是基于猜测来提供实用的示例,以便正确地索引表和查询。

本教程关注的重点是 MySQL、MariaDB 和 PerconaDB 数据库。这些信息也可能与其他数据库供应商有关,但在某些情况下可能不会。

我应该为我的 SQL 查询创建哪些索引?
根据通常的经验规则,当尝试优化你的 SQL 查询时,你可以依照以下步骤构建复合索引:

首先列出你的查询中所有使用的表,并为查询中的每个子查询创建一个独立的列表。如果你有一个包含 2 个 SELECT 子查询的 SELECT 查询,那你应该建立 3 个列表,每个列表包含引用在其中的表。
在此过程结束时,你可能会在每个查询列表中为每个这些表添加一个列的列表。

在你的任何索引中最左边的列应与查询相等比较(如 age = 25)中的列匹配。
你可以添加多个列,只要所有列与常量进行比较相等即可。

那么,你应该选择一个列,这将是“范围列(range column)”。MySQL 在每个索引中只支持一个范围列。
因此,你应该使用范围运算符(<>, >, <, IN(), BETWEEN, LIKE)来查看所有的比较,并选择可以过滤最多行数的那个。
将该列给该表添加为你的索引中的下一列。
你可以在这里获得一些信息 —— 关于在范围列之前添加相等列的理由(幻灯片由一位 MySQL 优化团队的成员编写)。

如果查询中不存在范围列,你可以添加 GROUP BY 子句中的列。

如果查询中不存在范围列,并且没有 GROUP BY 子句,则可以添加 ORDER BY 子句中的列。

在某些情况下,创建一个独立的索引来保存 ORDER BY 子句的列是有意义的,因为 MySQL 有时会选择使用它。请注意,尽管如此,索引应该包含 ORDER BY 子句中的所有列,它们应该全部在 ORDER BY 子句中用相同的顺序(ASC / DESC)指定。这并不能保证数据库的优化器会选择这个索引而不是 WHERE 复合索引,但是值得一试。

最后,从 SELECT 子句中添加相关的列,这可能允许 MySQL 使用索引作为覆盖索引。覆盖索引是包含过滤和查询子句中的所有列的索引。这样的索引允许数据库仅通过使用索引运行查询,而不需要访问表。在许多情况下,这种方法显然更快。        

我们通过一个示例来说明:

SELECT id, first_name, last_name, age from employees where first_name = ‘John’ AND last_name = ‘Brack’ and age > 25 ORDER BY age ASC;
对于这个查询,我们将以添加 first_name 和 last_name 列开始,它们与等号运算符进行比较。然后,我们将添加与范围条件进行比较的 age 列。这里不需要在 ORDER BY 子句索引,因为 age 列已经在索引中了。最后同样重要的是,我们将从 SELECT 子句中添加 id 到索引以生成 covering 索引。         

所以为了正确的索引这个查询,你应该添加以下索引:
employees (first_name, last_name, age, id)

以上是一个非常简化的伪代码算法,可以让你为相当简单的 SQL 查询构建简单的索引。

如果你正在寻找一种方法来实现这个过程的自动化,并希望增强专有索引算法和查询优化的好处,你可以试用 EverSQL Query Optimizer,它为你做了所有繁重的工作。   

索引(或编写 SQL 查询)时不应该做什么?
我们收集了一些程序员和数据库管理员在编写查询和索引表时遇到的最常见的错误。

将表中的每一列分别索引
在大多数情况下,MySQL 将不能在查询中为每个表使用多个索引。

因此,当为表中的每一列创建一个单独的索引时,数据库只能使用索引执行其中一个搜索操作,而其余部分将显着较慢,因为数据库不能使用索引执行它们。

我们建议使用复合索引(本文稍后解释)而不是单列索引。

filtering 条件中的 OR 运算符
考虑以下查询语句:

SELECT a, b FROM tbl WHERE a = 3 OR b = 8
在许多情况下,MySQL 将无法使用索引来应用 OR 条件,所以,此查询是不可索引的。

因此,我们建议避免这种 OR 条件,并考虑将查询拆分为两部分,并结合 UNION DISTINCT 使用(或者最好使用 UNION ALL,以防你不知道其中不会有任何重复的结果)      

在索引中列的顺序十分重要
比方说,我把我的联系人电话簿交给你,电话簿是按照联系人的名字排序的,要求你找出电话簿中有多少人名为“John”。你会接过电话簿,说“没问题”。你将找到包含以 John 开头的所有名字的页面,并从此处开始计数。

现在,假设我改变了任务,并给你一个按联系人的姓氏排序的电话簿,但要求你仍然统计以“John”作为名字的所有联系人。你会怎么做? 同样的,数据库在这种情况下也会很为难的。

现在让我们看看一个 SQL 查询来演示使用 MySQL 优化器时相同的行为:

SELECT first_name, last_name FROM contacts WHERE first_name = ‘John’;
拥有索引的联系人(first_name, last_name)在这里是理想的,因为索引从我们的筛选条件开始,然后在 SELECT 子句中以另一个列结束。

但是,具有反向索引的联系人(last_name,first_name)是相当没有意义的,因为数据库不能使用索引过滤,作为列,我们需要的是索引中的第二个,而不是第一个。

这个例子的结论是,索引中的列顺序非常重要。      

增加的冗余索引
当你试图优化你的 SQL 查询时,索引是非常有意义的,它可以显著地提高性能。

但是,这也有不利的一面。你创建的每个索引都应该保持更新,并在数据库中发生更改时保持同步。因此,对于数据库中的每个 INSERT / UPDATE / DELETE,都应更新所有相关索引。此更新可能需要较长的时间,特别是对于大型的表/索引。

所以,除非你知道你需要它们,否则不要创建索引。

另外,我们强烈推荐在某一段时间内分析一下数据库,搜索任何可以删除的冗余索引。

 

分享到:
评论

相关推荐

    Mysql优化选择最佳索引的方法共2页.pdf.zip

    本篇将深入探讨MySQL中如何优化选择最佳索引的方法。 首先,我们需要理解索引的基本原理。索引是一种特殊的数据结构,它存储了表中一列或多列值的排序,使得数据库系统能够快速找到数据行。常见的索引类型包括B-...

    MySQL索引原理及慢查询优化1

    MySQL索引原理及慢查询优化是数据库管理中的重要主题,尤其是在高并发、大数据量的...通过合理的索引设计、查询优化以及对磁盘IO的理解,可以有效避免和解决慢查询问题,从而让MySQL在各种应用场景中发挥出最佳性能。

    04-VIP-Mysql索引优化实战一.pdf

    总之,MySQL索引优化涉及到对查询语句的理解、索引设计的合理性以及根据数据量和查询模式选择合适的索引使用策略。在实际应用中,应结合`EXPLAIN`分析、性能测试和业务需求来调整索引和查询方式,以达到最佳的数据库...

    mysql性能优化之索引优化

    MySQL的查询优化器会根据不同的查询条件和索引选择最佳的执行计划。然而,有时候优化器可能选择的不是最优路径,这时可以通过EXPLAIN命令来分析查询计划,调整索引或查询语句以达到更好的性能。 总的来说,MySQL的...

    MySQL 索引最佳实践

    详细讲解mysql优化过程。” 在MySQL数据库中,索引扮演着至关重要的角色,它不仅能够显著提升数据查询的速度,还能帮助执行某些约束(如唯一性和外键)。然而,不当的索引选择可能会导致生产环境中的大量问题。本文...

    MySQL的or、in、union与索引优化

    ### MySQL的or、in、union与索引优化 在数据库查询优化中,索引的使用至关重要,它能显著提升查询速度。本文将基于一个具体的业务场景来探讨在MySQL中使用`union all`、`in`、`or`以及负向查询(如`!=`)时如何有效...

    MySQL索引最佳实践

    ### MySQL索引最佳实践 #### 一、理解MySQL索引的重要性 索引是数据库性能优化中最常用也是最重要的手段之一。合理的索引设计可以显著提高查询效率,减少服务器资源的消耗。在MySQL中,索引的选择与配置对于开发...

    MySQL性能优化的最佳20+条经验

    为查询缓存优化你的查询 随着业务规模的不断扩大,数据库操作往往成为整个应用程序的性能瓶颈,特别是在Web应用领域更为突出。因此,不仅DBA需要关注数据库性能问题,开发者在设计数据库表结构以及编写SQL查询语句...

    mysql高级优化查询

    查询优化器负责选择最佳的查询执行计划。它会根据表的统计信息、索引结构等因素来决定如何执行 SQL 语句,以达到最优的执行效率。 ### 三、其他高级优化策略 #### 3.1 分区 分区是一种物理划分数据的方法,可以...

    MySQL查询优化浅析

    物理优化阶段则专注于选择最佳的执行策略,包括表的访问顺序、索引的选择以及连接操作的类型等。 #### MySQL Range Optimizer详解 Range Optimizer是MySQL查询优化器的重要组成部分,专门用于处理基于索引的范围...

    MySQL性能优化的最佳21条经验

    以下是从"MySQL性能优化的最佳21条经验"中提取的一些关键知识点: 1. **索引优化**:索引是提升查询速度的关键,合理创建主键、唯一键和普通索引,避免全表扫描。使用覆盖索引可以减少磁盘I/O。 2. **选择合适的...

    MySQL性能优化的最佳经验

    为查询缓存优化你的查询 查询缓存是MySQL中的一项内置功能,它能够显著提升数据库性能。当多个相同的查询请求频繁发生时,查询结果会被缓存起来,后续相同的查询可以直接从缓存中读取结果,避免重复执行查询操作。...

    mysql索引优化深入1

    这表明MySQL的查询优化器可以自动处理索引顺序,但最佳实践是按照查询条件的频率和顺序来构建索引。 Case 2揭示了范围查询对索引的影响。当存在范围查询(例如,`BETWEEN`或`&gt;`操作符)时,type变为range,key_len...

    MySQL查询优化器的工作原理

    MySQL查询优化器是数据库管理系统(DBMS)的一个核心组件,它负责分析SQL查询语句,并决定执行查询的最佳路径或方式,从而保证查询的效率和性能。优化器的最终目标是找到一种成本最低的方式来执行SQL语句,它会考虑...

    mysql存储与索引技术

    应根据应用需求选择合适的存储引擎,合理设计索引结构,同时关注索引带来的存储和性能影响,以实现数据库的最佳运行状态。在实践中,定期评估和调整索引策略,结合具体的业务场景进行优化,是保持数据库高效运行的...

    高效MySQL查询加速指南:索引策略、查询优化、性能调优,助力数据库管理员和开发者突破性能瓶颈

    ### 高效MySQL查询加速指南:索引策略、查询优化、性能调优 在数据库管理和开发领域中,MySQL因其灵活性和高效性而受到广泛欢迎。然而,在面对大规模数据集时,即使是性能强大的MySQL也可能遇到查询速度慢的问题。...

Global site tag (gtag.js) - Google Analytics