MySQL解释中过滤是什么意思?

Ima*_*ang 36 mysql innodb mysql-5.7

MySQL 文档中所述

过滤的列指示将由表条件过滤的表行的估计百分比。也就是说,rows 显示估计的检查行数,而 rows × filters / 100 显示将与先前表连接的行数。在 MySQL 5.7.3 之前,如果使用 EXPLAIN EXTENDED,则会显示此列。从 MySQL 5.7.3 开始,默认启用扩展输出,不需要 EXTENDED 关键字。

我还是不明白。这里的“过滤”是什么意思?我们可以从这个专栏中得到什么信息?

例如,当我开始查询时,有些查询会显示 100,而有些查询会显示 18 或任何低于 100 的值。

+-------------+-------+--------+---------+---------+------+----------+
| select_type | table | type   | key     | key_len | rows | filtered |
+-------------+-------+--------+---------+---------+------+----------+
| PRIMARY     | a     | range  | search  | 4       |  174 |   18.00  | <--
| PRIMARY     | b     | eq_ref | PRIMARY | 4       |    1 |   100.00 |
| PRIMARY     | c     | ALL    | PRIMARY | 4       |    1 |   100.00 |
Run Code Online (Sandbox Code Playgroud)

我们可以从这个值中得出什么要点?

是不是说,该列仅过滤了 18%?或者,如果分数越低,索引/查询就越好?

我正在使用 MySQL 5.7

Sol*_*are 57

这里过滤意味着对由type-search选择为潜在行的一组行应用条件,并且只保留满足条件的行:

MySQL 将首先尝试使用索引,例如使用-keyrange对您的表a进行扫描search。它估计使用该索引可以获得 174 行,这是rows. 这一步还不称为过滤。

之后,必须根据其他条件(通常在您的where-clause 中)检查这 174 行。MySQL 现在估计只有 32 行,所以这 174 行中的 18% 将在应用该过滤器后保留。这 18% 是 中的值filtered

虽然拥有 32 行而不是 174 行显然更好(例如,如果您必须稍后join使用另一个表),但“完美”索引会直接从初始搜索中为您提供这 32 行,从而节省您查看的时间并过滤掉所有潜在行的 82%。

因此,较低的值可能表明可能存在更好的索引:例如,如果您添加了一个好的索引,则可以使用rows=1000和进行全表扫描,并且filtered=0.1%可以成为索引查找。rows=1filtered=100%

另一方面,您可以完全忽略此filtered-value(无论如何在大多数情况下这是一个非常糟糕的估计),并专注于其他更重要的列(尤其是type,keyextra)以优化您的查询。例如,最好去掉 a filesort(例如,通过使用满足 的索引order by),即使它导致较低的filtered值。更好的type可以带来巨大的性能提升,即使它可能不会改变甚至更低filtered。在上面的示例中,filtered=0.1%,type=all已经足以表明您可以通过添加索引来改进该查询,而filtered根本不需要查看。

所以不要太认真地对待这个值:既不100意味着你的索引是好的,较低的值也不一定表明索引不好。type是一个更好的指标。

  • 另一个提示:过滤后的计算将跳过最后加入的表。也就是说,它会显示 100%,即使实际上有条件会过滤掉一些检查过的行。理由是估计过滤因子需要一些成本,如果它在最后一个表上,这不会影响查询执行计划,因此他们默认跳过计算。 (3认同)