mysql - MySQL 将在什么执行级别使用 ORDER BY 索引?

标签 mysql sql

我想了解MySQL在使用ORDER BY时会在什么时间点使用索引列。

例如查询

SELECT * FROM A
INNER JOIN B ON B.id = A.id
WHERE A.status = 1 AND A.name = 'Mike' AND A.created_on BETWEEN '2014-10-01 00:00:00' AND NOW()
ORDER BY A.accessed_on DESC

据我所知,上述查询的一个好的索引是表 A (id, status, namecreated_on,accessed_on) 上的索引和 B.id 上的另一个索引.

我还了解到SQL执行遵循以下顺序。但我不确定订单选择和订单如何运作。

  1. FROM 子句
  2. WHERE 子句
  3. GROUP BY 子句
  4. HAVING 子句
  5. SELECT 子句
  6. ORDER BY 子句

问题

使用 id 列启动索引是否会更好,或者在这种情况下并不重要,因为 WHERE 在 JOIN 之前先执行?或者应该是

第二个问题accessed_on列应该位于索引组合的开头、末尾还是中间?或者 id 列应该位于 WHERE 子句中的所有列之后吗?

我很欣赏详细的答案,这样我就可以了解 MySQL/SQL 的执行级别

已更新

我向表 A 和表 B 添加了几百万条记录,然后添加了多个索引来查看哪个是最佳索引。但是,MySQL 似乎喜欢索引 id_2 (即(status、name、created_on、id、accessed_on))

它似乎正在应用 where ,它会发现它需要对状态、名称、created_on 进行索引,然后它会应用 INNER JOIN 并使用 id index 后跟第一个 3。最后,它将查找 access_on 作为最后一列。因此索引(status, name,created_on,id,accessed_on)符合相同的执行顺序

这是表结构

CREATE TABLE `a` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `status` int(2) NOT NULL,
  `name` varchar(255) NOT NULL,
  `created_on` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `accessed_on` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `status` (`status`,`name`),
  KEY `status_2` (`status`,`name`,`created_on`),
  KEY `status_3` (`status`,`name`,`created_on`,`accessed_on`),
  KEY `status_4` (`status`,`name`,`accessed_on`),
  KEY `id` (`id`,`status`,`name`,`created_on`,`accessed_on`),
  KEY `id_2` (`status`,`name`,`created_on`,`id`,`accessed_on`)
) ENGINE=InnoDB AUTO_INCREMENT=3135750 DEFAULT CHARSET=utf8


CREATE TABLE `b` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3012644 DEFAULT CHARSET=utf8

最佳答案

此查询的最佳索引是:A(status, name,created_on)B(id)。这些索引将满足 where 子句,并使用索引连接到 B

该索引不会用于排序。使用任何索引进行排序有两个主要障碍。第一个是加入。第二个是 created_on 上的不相等。有些数据库可能会想出在 A(status, name,accessed_on) 上使用索引,但我认为 MySQL 不够智能。

您不希望 id 作为索引中的第一列。这会阻止使用索引对 A 进行过滤,因为 id 用于 join 而不是在 where 中.

关于mysql - MySQL 将在什么执行级别使用 ORDER BY 索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27585849/

相关文章:

mysql - 如何将数组保存在一列中?

mysql - 删除在 phpmyadmin 中未被识别为关键字

mysql - 如何通过加入 codeigniter 从 SQL 查询中删除表中的冗余数据

sql - 无法对 SQL Server 中的所有行应用计算

java - 在 Android 的 SQLite 数据库中保存 ArrayList

c# - 这种方法使用安全吗?

mysql - 在 MySQL Server 中创建一个以一对作为主键的表

mysql - 如果用户子集中的任何一个给某个项目特定的评级,如何从 mySQL 选择中排除项目?

php - php 文件未收到数据库响应

php - 基于两个数组数据选择查询时如何避免循环