在mysql中是否有索引“跳跃”这样的东西?

qhhrdooz  于 2021-07-24  发布在  Java
关注(0)|答案(3)|浏览(189)

假设我们在(a,b)上有一个索引,在(b,c)上有一个索引。执行以下查询时:

SELECT * FROM table WHERE A = const AND B = const ORDER BY C DESC

查询优化器是否会首先搜索(a,b)索引以筛选where类的行,然后使用(b,c)索引快速排序?
或者查询仅限于一个索引?不跳b树?

rkttyhzu

rkttyhzu1#

不,mysql没有像你描述的那样。
它将执行以下操作之一:
从报纸上读到 (A, B) 索引,它将使用索引只检查匹配的行,但需要额外的工作来执行文件排序以按 C .
从报纸上读到 (B, C) 索引,它将按正确的顺序读取行,从而跳过文件排序。但它将检查许多额外的行,这些行的值为 A 不匹配的行,它必须逐个计算这些行,并丢弃不匹配的行。
您可以通过替换 (A, B) 启用索引的索引 (A, B, C) 这将只检查匹配的行,并按所需顺序读取它们,因此不需要文件排序。
innodb总是以某种索引顺序读取行。二级索引或聚集索引。
回答您的问题:
一般来说,mysql每个表引用只读取一个索引。例如,这允许使用自联接进行查询,以便同一个表有多个表引用。每个表引用可能使用不同的索引读取。
例如,管理者与员工的自我联结:

SELECT ...
FROM employees AS m
JOIN employees AS e ON e.manager_id = m.id
WHERE m.hire_date = '2020-01-01'

在本例中,它可能在 hire_date 选择管理器和上的索引 manager_id 为经理的下属。这是两个不同的表引用,因此它们是分开读取的。
mysql还有一个称为索引合并优化的特性,它可以读取表的两个子集,可能使用不同的索引,然后使用并集或交集合并结果。但我发现这并不像你想象的那么频繁。
关于desc的订单,https://dev.mysql.com/doc/refman/8.0/en/descending-indexes.html 说:
以前,索引可以按相反的顺序扫描,但性能会受到影响。
在mysql 8.0中,他们实现了对声明一个按降序构建的索引的支持,以支持order-by-desc查询。但是索引是为这些查询定制的,使用相同的索引进行asc查询会受到影响。因此,可能需要在同一表的同一列上创建两个索引。阅读我链接到的文档页面了解更多详细信息。

plupiseo

plupiseo2#

当然,你可以测试你的数据。但根据我的经验,指数首先要和 where 条款。所以,它会匹配 (A, B) 索引。
然后它将对排序执行排序。

628mspwn

628mspwn3#

你问:
查询优化器会首先在(a,b)索引中搜索以筛选where类的行吗?
是的,mysql可能会使用第一个索引来检索行,如果 predicate 与 UNIQUE 约束。
…然后使用(b,c)索引快速排序?
不。第二个索引不包括使用第一个索引筛选的行。引擎将检索所有行(不再使用管道),对它们进行排序,然后将它们提供给您。如果有很多行,这个阶段将是资源密集型的,而且速度很慢。希望筛选 predicate 只产生几行。

相关问题