Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有索引之类的东西吗;“跳跃”;在MySQL中?_Mysql_Sql_Database_Indexing_Database Design - Fatal编程技术网

有索引之类的东西吗;“跳跃”;在MySQL中?

有索引之类的东西吗;“跳跃”;在MySQL中?,mysql,sql,database,indexing,database-design,Mysql,Sql,Database,Indexing,Database Design,假设我们在(A,B)上有一个索引,在(B,C)上有一个索引。执行以下查询时: SELECT * FROM table WHERE A = const AND B = const ORDER BY C DESC 查询优化器是否会首先搜索(A,B)索引以筛选WHERE类的行,然后使用(B,C)索引快速排序 或者查询仅限于一个索引?没有B-树跳跃?当然,您可以对数据进行测试。但根据我的经验,索引首先要匹配where子句。因此,它将在(A,B)索引上匹配 然后,它将对排序执行排序。不,MySQL没有执

假设我们在(A,B)上有一个索引,在(B,C)上有一个索引。执行以下查询时:

SELECT * FROM table WHERE A = const AND B = const ORDER BY C DESC
查询优化器是否会首先搜索(A,B)索引以筛选WHERE类的行,然后使用(B,C)索引快速排序


或者查询仅限于一个索引?没有B-树跳跃?

当然,您可以对数据进行测试。但根据我的经验,索引首先要匹配
where
子句。因此,它将在
(A,B)
索引上匹配


然后,它将对排序执行排序。

不,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\u date
上的索引选择经理,并使用
manager\u id
上的索引选择经理的下属。这是两个不同的表引用,因此它们是分开读取的

MySQL还有一个称为an的特性,它可以读取表的两个子集,可能使用不同的索引,然后使用并集或交集合并结果。但我发现这并不像你想象的那样频繁

关于DESC的订单,他说:

以前,可以按相反的顺序扫描索引,但会降低性能

在MySQL 8.0中,他们实现了对声明索引以降序方式构建的支持,以支持按DESC顺序查询。但是,索引是针对这些查询定制的,使用相同的索引进行ASC查询将受到影响。因此,您可能需要在同一个表的相同列上创建两个索引。阅读我链接到的文档页面以了解更多详细信息。

您会问:

查询优化器会首先在(A,B)索引中搜索以筛选WHERE类的行吗

是的,MySQL可能会使用第一个索引来检索行,使用带有开始和停止谓词的“索引范围扫描”,或者如果谓词匹配
唯一的
约束,则使用“索引查找”

…然后使用(B,C)索引快速排序


没有。第二个索引不包括使用第一个索引筛选的行。引擎将检索所有行(不再使用管道),对它们进行排序,然后将它们提供给您。如果有许多行,此阶段将是资源密集型且缓慢的。希望筛选谓词只产生几行。

ORDER BY子句是DESC有什么区别吗?此外,查询是否总是局限于使用一个索引?@LudovicoVerniani-我非常肯定,即使在这种情况下,DESC也会得到尊重和高效。(无文件排序)。在MySQL 8.0之前应该是这样的,它在索引定义中尊重DESC。比尔,你听说过“以前……反向顺序”是否不仅仅是一个小惩罚吗?@RickJames,Jeremy Cole在InnoDB内部的演示。但说到这里,他并没有量化它,我也并没有亲自测量它。我制作了一个粗略的测试——它表明DESC的速度略有放缓,但并不显著。MySQL很少使用两个索引。但仅适用于和或或,不适用于ORDER BY。两个半相关的研究内容:“MRR”和“松散扫描”。有趣的话题,感谢您提及@RickJames