use*_*464 8 mysql database indexing
我正在阅读高性能MySQL,我对延迟加入感到有点困惑.
该书说,以下操作无法通过索引(性别,评级)进行优化,因为高偏移要求他们花费大部分时间扫描大量数据然后丢弃.
mysql> SELECT <cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 100000, 10;
Run Code Online (Sandbox Code Playgroud)
虽然延迟连接有助于最大限度地减少MySQL必须收集的数据,而这些数据只会丢弃.
SELECT <cols> FROM profiles INNER JOIN (
SELECT <primary key cols> FROM profiles
WHERE x.sex='M' ORDER BY rating LIMIT 100000, 10
) AS x USING(<primary key cols>);
Run Code Online (Sandbox Code Playgroud)
为什么延迟连接会最小化收集的数据量.
您提供的示例假设使用 InnoDB。假设PRIMARY KEY是id。
INDEX(sex, rating)
Run Code Online (Sandbox Code Playgroud)
是“辅助键”。每个辅助键(在 InnoDB 中)都隐式包含 PK,因此它实际上是一个有序的(sex, rating, id)值列表。为了获取“数据”( <cols>),它使用id向下钻取 PK BTree(也包含数据)来查找记录。
快速案例:因此,
SELECT id FROM profiles
WHERE x.sex='M' ORDER BY rating LIMIT 100000, 10
Run Code Online (Sandbox Code Playgroud)
将对索引中的 100010 行进行“范围扫描”。这对于 I/O 来说非常高效,因为所有信息都是连续的,不会浪费任何东西。(不,它不够聪明,无法跳过 100000 行;那会很混乱,尤其是当您考虑 transaction_isolation_mode 时。)这 100010 行可能适合索引的大约 1000 个块。然后它得到 的 10 个值id。
使用这 10 个 id,它可以执行 10 次连接(“NLJ”=“嵌套循环连接”)。这 10 行很可能分散在表周围,可能需要对磁盘进行 10 次命中。
让我们“计算磁盘命中数”(忽略 BTree 中的非叶节点,它们无论如何都可能被缓存):1000 + 10 = 1010。在普通磁盘上,这可能需要 10 秒。
慢案例:现在让我们看一下原始查询 ( SELECT <cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 100000, 10;)。让我们继续假设最后INDEX(sex, rating)加上隐式。id
和以前一样,它将索引扫描 100010 行(估计 1000 次磁盘命中)。但事实上,做上面的事情太愚蠢了。它将深入数据以获取<cols>. 这通常(取决于缓存)需要随机磁盘命中。这可能会超过 100010 次磁盘命中(如果表很大并且缓存不是很有用)。
再次,抛出 100000 个,交付 10 个。总“成本”:100010 次磁盘命中(最坏情况),可能需要 17 分钟。
请记住,高性能 MySQL有 3 个版本;它们是在过去 13 年左右的时间里写成的。您可能使用的 MySQL 版本比他们所介绍的要新得多。我不知道优化器在这方面是否变得更聪明。这些(如果您有的话)可能会提供线索:
EXPLAIN FORMAT=JSON SELECT ...;
OPTIMIZER TRACE...
Run Code Online (Sandbox Code Playgroud)
我最喜欢的“处理程序”技巧对于研究事物如何工作可能会有所帮助:
FLUSH STATUS;
SELECT ...
SHOW SESSION STATUS LIKE 'Handler%'.
Run Code Online (Sandbox Code Playgroud)
您可能会看到 100000 和 10 等数字,或此类数字的小倍数。但是,请记住,索引的快速范围扫描每行计为 1,对于一大组<cols>.
概述:为了使该技术发挥作用,子查询需要一个“覆盖”索引,并且列的顺序正确。
“覆盖”意味着(sex, rating, id)包含所有触及的列。(我们假设<cols>包含其他列,也许是在 . 中无法工作的庞大列INDEX。)
列的“正确”排序:列的顺序正好可以完成查询。(另请参阅我的食谱。)
WHERE进行比较的任何列。=( sex)ORDER BY,按顺序。( rating)id)| 归档时间: |
|
| 查看次数: |
925 次 |
| 最近记录: |