【问题标题】:SQL: the order of "BETWEEN AND" and "<> (!=)" [duplicate]SQL:“BETWEEN AND”和“<> (!=)”的顺序 [重复]
【发布时间】:2017-05-21 07:25:59
【问题描述】:

一条sql查询:

例如:

  1. select id from user where age != 20 and age between 18 and 30;

  2. select id from user where age between 18 and 30 and age != 20;

以上只是一个简单的例子。

问题:

如果数据很多,上面两个语句在性能上会有什么区别? 我该如何选择呢?

提示: 如果字段“年龄”已经有索引。

与上面的问题不同。我被问到的问题是:

我不关心"where"的顺序,我只关心&lt;&gt;bewteen and的不同顺序是否有不同的效果,因为它们属于查询范围,查询范围可能存在数据倾斜问题。

就像@axiac 说的那样

【问题讨论】:

  • 使用 EXPLAIN 查看查询优化器在做什么

标签: mysql sql between


【解决方案1】:

Afaik MySQL 查询优化器会为您的两个查询生成相同的执行计划。它使用索引仅检查具有age between 18 and 30 的行,然后,对于每一行,它检查条件age != 20(也使用索引中的数据)。

上面的解释假设age 列中的值是不同的。 MySQL 首先使用age between 18 and 30 条件,因为它过滤掉的行比age != 20 多。但是,如果表中的数据不平衡并且表中的大部分行都有age = 20,那么MySQL会首先选择这个age != 20条件(因为它比另一个条件消除了更多的行)。

我不知道必须有多少行 age = 20 才能让查询优化器使用 age != 20 条件进行过滤,但我确信百分比必须很高;如果您表中的人是从有限的群体中选择的(例如同一年学习的学生),它可能会达到阈值,但如果表中的年龄服从正态分布,它肯定不会达到阈值。

MySQL 在运行查询时根据表中的实际数据使用一种或另一种条件来过滤尽可能多的行。当表中的数据发生变化时,它可以在以后更改执行计划。

如果id 是您的表的PK,它在age 上有一个索引并且它使用InnoDB 引擎,那么上面的查询不需要读取表数据。 WHERE 条件和SELECT 表达式都可以使用索引信息进行评估。我会说它没有进一步优化的可能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-05
    • 2012-11-14
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    相关资源
    最近更新 更多