mysql - 'and' 和 'or' 在 SQL 中是如何工作的

标签 mysql sql innodb

假设我有一个大型网站的数据库,其中有一个名为“用户”的表,其中包含大量记录。当我执行诸如 SELECT * FROM users WHERE username='John' 之类的查询时,我的理解是(忽略缓存等)数据库将导航索引并找到名为 John 的用户。假设此查询返回 100 万个结果,而我只对 John 25 岁的用户感兴趣,因此我执行另一个查询:SELECT * FROM users WHERE username='John' AND age=25

这是如何运作的?它会遍历所有名为 John 的用户并只找到年龄匹配 25 岁的用户,还是有更好的方法?我假设这是特定于数据库和存储引擎的,因此我们可以假设我正在使用 MySQL 和 InnoDB。

最佳答案

答案是——你不应该问这个问题。在像 SQL 这样的声明性语言中,您描述所需的结果,然后处理引擎确定生成结果的最佳方式。根据请求中看似微小的差异,可能会采用不同的路径获得结果,或者使用的方法可能因产品版本而异,甚至基于与产品完全无关的某些因素(可用内存或磁盘空间) ,例如)。

也就是说,在大多数情况下,以下情况适用于大多数 SQL 数据库:

  1. 数据库将仅使用一个索引来评估 WHERE 子句。
  2. 如果可以使用多个索引来评估 WHERE 子句,数据库将使用有关每个索引中的基数(值的分布)的统计信息来选择“最佳”索引。
  3. 如果有一个由多个列构建的索引,并且该索引的 head 列出现在 WHERE 子句的过滤条件中,则该索引可能用于按单个索引中的多列过滤。

因此,在您的示例中,大多数数据库会使用年龄或姓名索引来进行第一级过滤,然后扫描生成的记录以进行第二级过滤。唯一的异常(exception)是,如果您在 (name, age) 或 (age, name) 上有复合索引,在这种情况下,只需要索引扫描即可找到记录。

关于mysql - 'and' 和 'or' 在 SQL 中是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27350485/

相关文章:

SQL - 计算一个属性,按另一个分组

mysql - CREATE TABLE 不适用于 InnoDB,但适用于 MyISAM

Mysql 将列字符串拆分为三行

php - 按指定顺序选择匹配行前后的行

MySQL - 获取 COUNT 取决于值

mysql - 如果删除了两个外键,则删除表条目

mysql - innodb 的 data_length 和 index_length 没有改变

mysql - 为什么 TokuDB 和 InnoDB 插入比 MyISAM 慢

来自 Mysql DateTime 字符串的 C++ unix 时间

mysql - 是否可以通过查看执行计划来了解为什么我的查询如此缓慢