如MySQL文档中此处所述:


Filtered列指示将按表条件过滤的表行的估计百分比。也就是说,行显示了检查的行的估计数,行×过滤后的行数/ 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 |
 


我们可以从该值得出什么主要结论?

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

我正在使用MySQL 5.7

#1 楼

在此处进行过滤意味着对由type -search选择为潜在行的一组行应用条件,并仅保留满足条件的行:

MySQL首先将尝试使用索引,例如使用range -key在表a上进行search扫描。估计使用该索引(即rows中的数字)可获得174行。此步骤尚未称为过滤。

之后,必须对照附加条件(通常在where -clause中)检查这174行。 MySQL现在估计只有32行,因此在应用该过滤器后将保留这174行中的18%。这18%是filtered中的值。

用32行代替174行显然更好(如果以后要用另一个表join),则“完美”索引应该直接从初始搜索中获得这32行,可以节省您查看和过滤所有潜在行的82%的时间。

因此,较低的值可能表示索引可能更好:例如如果您添加良好的索引,则使用rows=1000filtered=0.1%进行全表扫描可能会使用rows=1filtered=100%进行索引查找。另一方面,您可以完全忽略此filtered -value(这是在大多数情况下,无论如何还是一个非常糟糕的估计),并专注于其他更重要的列(尤其是typekeyextra)来优化您的查询。它可以例如最好放弃filesort(例如,通过使用满足order by的索引),即使它导致较低的filtered值也是如此。更好的type可以带来巨大的性能提高,即使它可能不会改变甚至更低。在上面带有filtered的示例中,filtered=0.1%足以表明您可以通过添加索引来改善该查询,而无需完全查看type=all

因此,不要太在意该值:filtered既不表示您的索引很好,也不低表示该索引不好。 100是一个更好的指标。

评论


感谢您的解释。这为我解释了很多。我认为这对于维护和选择良好的索引很有用

–伊曼·图莫朗(Iman Tumorang)
17年2月15日在1:16

@ImanTumorang我添加了一个评论和一个有关此示例:不要太重视该值。您可以仅查看类型和其他内容(这本身就是一门艺术)来优化查询;您可能没有过滤就生活了,但没有类型就没有了。

–太阳耀斑
17年2月15日在11:35

好吧。我知道了。我已经在Mysql Docs中阅读了它们如何影响性能。谢谢您的解释:D

–伊曼·图莫朗(Iman Tumorang)
17年2月16日在13:30

另一个提示:筛选的计算将跳过最后一个联接的表。也就是说,即使实际上有条件会过滤掉某些检查的行,它也会显示100%。理由是估计筛选因子会花费一些钱,并且如果它在最后一张表上,这不会影响查询执行计划,因此它们默认跳过计算。

– Bill Karwin
19年11月28日在17:22