首页 > 编程知识 正文

mysql索引最左匹配原则的理解,mysql左like能不能走索引

时间:2023-05-05 21:26:37 阅读:145360 作者:1931

索引可以做什么?

索引主要做三件事:过滤(过滤器)、排序或分组(sort/group )和覆盖)。

基本查询的工作流程如下:

1 .使用索引查找匹配记录并获得指向数据的指针。

2 .使用相关数据的指针

3 .返回查询的记录。

如果可以使用覆盖索引,则索引将覆盖查询中的所有字段,因此跳过步骤2,查询过程如下:

1 .使用索引查找匹配的记录

2 .返回查询的记录。

大多数情况下,索引相对较小,可以加载到内存中,但数据较大,不能全部存储在内存中。 使用覆盖索引还可以大大提高性能,因为它可以避免许多磁盘操作。

现在,我们来看看典型的查询示例。

单等于查询(单质量) )

这是最基本的方案:

SELECT * FROM t WHERE c=100

在这种情况下,毫无疑问要在c字段中创建索引。 应当注意的是,如果查询条件不够准确(不能理解ifthecriteriaisnotselectiveenough这个词),优化程序很可能会选择所有表查询。 因为可能会提高性能。

这等于查询还包括仅查询某些字段,而不是所有字段,如下所示:

SELECT c1,c2 FROM t WHERE c=100

应该在此处索引(c、c1、c2 )。 因为这将涵盖索引。 注意不是创建(c1、c2、c )! 这同样涵盖索引,但对过滤没有什么帮助(记住MySQL索引的最左侧原则)。

多个等于查询(多质量) ) ) ) ) ) ) )。

select * fromtwherec=100 an DDD=' XYZ '

这种情况下也很容易优化。 创建索引(c,d )或(d,c )。

最常见的错误是创建两个索引。 一个是c,另一个是d。 虽然MySQL可以基于index_merge算法同时使用这两个索引,但这仍然是一个糟糕的选择。 有关详细信息,请参阅以下文章。 https://www.percona.com/blog/2009/09/19/multi-column-indexes-vs-index-merge/3359 www.percona.com/bbbb

等于和不兼容的查询(Equality and inequality ) )。

SELECT * FROM t WHERE c 100 and d='xyz '

在这种情况下,必须注意其他列不能使用索引,除非一列使用等于计算。

因此,必须为(d,c )创建索引。 此时,c和d两个条件都去索引。 这也是我们想要的结果。

另一方面,如果创建(c,d )索引,则只会使用c列的索引,从而降低效率。

因此,索引中字段的顺序对这种等于/等于混合的查询有很大影响。

示例:如果表students的合并索引为,则只使用第一个索引列phone。

如果表students的合并索引为:

多等于查询(多输入查询) )

select * fromtwherec 100 andb 10a ndd=' XYZ '

这里不是两个等于。 如上所述,如果不等于,索引查询将终止。 因此,索引不能覆盖b、c和d。 (评论1 )。 因此,必须决定是创建索引(d,b )还是索引(d,c )。

如果不知道表里的具体数据,制作上述的任何一个都可以。 最重要的是,必须将包含等于条件(在此为d )的列放在索引的最左侧。

示例:包含主键索引stud_id和联盟索引的表students的索引状态:

然后分析查询的结果。

附注1 )事实上,有一种“曲线救国”的方法可以同时满足所有条件。 也就是说,根据字段b生成分区(partition on b ),接着生成索引(d、c ),或者根据字段c生成分区(partition onc ),生成索引(d、b )。 这个细节超出了本文的讨论范围,这也是这种情况下的解决方案。

等于和排序多个(质量和排序) ) ) ) ) )。

select * fromtwherec=100 an DDD=' XYZ ' orderbyb

正如我在第一节中所写的,这个查询很容易优化,因为索引可以过滤和排序。 但是,正如不是等于一样,必须充分注意索引中字段的顺序。 必须过滤后再排序。

上述“先过滤后排序”要求表明,(c,d,b )或(d,c,b )是不错的选择。 另一方面,b、c、d )和b、d、c )只是排序而不过滤,所以很糟糕。

以下情况:

SELECT c1,C2 fromtwherec=100 an DD=' XYZ ' orderbyb

可以创建过滤、排序和封面的索引。 (c、d、b、c1、c2 )。

不等于和排序(Inequality and sort ) )。

常见的有两种。 以下情况1 (不是等于、等于或排序) :

select * fromtwherec 100 andd=' XYZ ' orderbyb

在这种情况下,有(d,b )或(d,c )两种想法。 哪个更有效率取决于数据,需要具体情况进行具体分析。

情况2如下。 (仅不等于排序) :

SELECT * FROM t WHERE c 100 ORDER BY b

这种情况下没有等于条件,所以b和c只能选择其中一个。 具体选哪个和你的数据一样。 通常,经常选择过滤。 也就是说,是c字段。

总结

这篇文章并不包括所有情况,但也指出了一些需要注意的地方。

请参阅文章:

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。