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=1000
和filtered=0.1%
进行全表扫描可能会使用rows=1
和filtered=100%
进行索引查找。另一方面,您可以完全忽略此filtered
-value(这是在大多数情况下,无论如何还是一个非常糟糕的估计),并专注于其他更重要的列(尤其是type
,key
和extra
)来优化您的查询。它可以例如最好放弃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