2KB项目,专业的源码交易网站 帮助 收藏 每日签到

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

  • 时间:2019-04-15 05:16 编辑:2KB 来源:2KB.COM 阅读:483
  • 扫一扫,手机访问
  • 分享
摘要:
MySQL 英文原文:Choosing the best indexes for MySQL query optimization

我们的很多用户、开发者和数据库***不时向我们的团队征询有关 EverSQL 的索引引荐算法。

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

本教程不会具体引见该算法的一切外部特征,而是要容易地阐明索引最主要的方面。别的,也是最主要的,我们将经过基于一套规矩而不是基于猜想来供给适用的示例,以便准确地索引表和查询。

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

我应当为我的 SQL 查询创立哪些索引?

依据凡是的经历规矩,当测验考试优化你的 SQL 查询时,你可以按照以下步调构建复合索引:

  1. 起首列出你的查询中一切运用的表,并为查询中的每一个子查询创立一个自力的列表。假如你有一个包括 2 个 SELECT 子查询的 SELECT 查询,那你应当树立 3 个列表,每一个列表包括援用在此中的表。
    在此进程完毕时,你可能会在每一个查询列表中为每一个这些表添加一个列的列表。

  2. 在你的任何索引中最右边的列应与查询相等比拟(如 age = 25)中的列适配。
    你可以添加多个列,只需一切列与常量实行比拟相等便可。

  3. 那末,你应当选择一个列,这将是“范畴列(range column)”。MySQL 在每一个索引中只支撑一个范畴列。
    因而,你应当运用范畴运算符(<>, >, <, IN(), BETWEEN, LIKE)来检查一切的比拟,并选择可以过滤最多行数的阿谁。
    将该列给该表添加为你的索引中的下一列。
    你可以在这里取得一些信息 —— 关于在范畴列之前添加相等列的来由(幻灯片由一名 MySQL 优化团队的成员编写)。

  4. 假如查询中不存在范畴列,你可以添加 GROUP BY 子句中的列。

  5. 假如查询中不存在范畴列,而且没有 GROUP BY 子句,则可以添加 ORDER BY 子句中的列。

  6. 在某些状况下,创立一个自力的索引来保管 ORDER BY 子句的列是成心义的,由于 MySQL 有时会选择运用它。请留意,虽然如斯,索引应当包括 ORDER BY 子句中的一切列,它们应当全体在 ORDER BY 子句顶用类似的次序(ASC / DESC)指定。这其实不能包管数据库的优化器会选择这个索引而不是 WHERE 复合索引,可是值得一试。

  7. 最初,从 SELECT 子句中添加相干的列,这可能答应 MySQL 运用索引作为掩盖索引。掩盖索引是包括过滤和查询子句中的一切列的索引。如许的索引答应数据库仅经过运用索引运转查询,而不需求拜访表。在很多状况下,这类办法明显更快。

其它翻译版本 (1) 加载中

我们经过一个示例来讲明:

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_namelast_name 列Start,它们与等号运算符实行比拟。然后,我们将添加与范畴前提实行比拟的 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 扫尾的一切名字的页面,并今后处Start计数。

如今,假定我改动了Task,并给你一个按联络人的姓氏排序的德律风簿,但请求你依然统计以“John”作为名字的一切联络人。你会怎样做? 异样的,数据库在这类状况下也会很难堪的。

如今让我们看看一个 SQL 查询来演示运用 MySQL 优化器时类似的行动:

SELECT first_name, last_name FROM contacts WHERE first_name = ‘John’;

具有索引的联络人(first_name, last_name)在这里是幻想的,由于索引从我们的挑选前提Start,然后在 SELECT 子句中以另外一个列完毕。

可是,具有反向索引的联络人(last_name,first_name)是相当没成心义的,由于数据库不克不及运用索引过滤,作为列,我们需求的是索引中的第二个,而不是第一个。

这个例子的结论是,索引中的列次序十分主要。

其它翻译版本 (1) 加载中

增加的冗余索引

当你试图优化你的 SQL 查询时,索引长短常成心义的,它可以明显地进步功能。

可是,这也有晦气的一面。你创立的每一个索引都应当坚持更新,并在数据库中发作更改时坚持同步。因而,关于数据库中的每一个 INSERT / UPDATE / DELETE,都应更新一切相干索引。此更新可能需求较长的工夫,特殊是关于大型的表/索引。

所以,除非你晓得你需求它们,不然不要创立索引。

别的,我们激烈引荐在某一段工夫内剖析一下数据库,搜刮任何可以删除的冗余索引

本文中的一切译文仅用于进修和交换目标,转载请务必注明文章译者、出处、和本文链接。 2KB翻译任务按照 CC 协议,假如我们的任务有进犯到您的权益,请实时联络我们。


2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务

  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【计算机/互联网|】Nginx出现502错误(2020-01-20 21:02)
【计算机/互联网|】网站运营全智能软手V0.1版发布(2020-01-20 12:16)
【计算机/互联网|】淘宝这是怎么了?(2020-01-19 19:15)
【行业动态|】谷歌关闭小米智能摄像头,因为窃听器显示了陌生人家中的照片(2020-01-15 09:42)
【行业动态|】据报道谷歌新闻终止了数字杂志,退还主动订阅(2020-01-15 09:39)
【行业动态|】康佳将OLED电视带到美国与LG和索尼竞争(2020-01-15 09:38)
【行业动态|】2020年最佳AV接收机(2020-01-15 09:35)
【行业动态|】2020年最佳流媒体设备:Roku,Apple TV,Firebar,Chromecast等(2020-01-15 09:31)
【行业动态|】CES 2020预览:更多的流媒体服务和订阅即将到来(2020-01-08 21:41)
【行业动态|】从埃隆·马斯克到杰夫·贝佐斯,这30位人物定义了2010年代(2020-01-01 15:14)
联系我们

Q Q: 7090832

电话:400-0011-990

邮箱:7090832@qq.com

时间:9:00-23:00

联系客服
商家入住 服务咨询 投拆建议 联系客服
0577-67068160
手机版

扫一扫进手机版
返回顶部