MySQL查询CASE WHEN公式的极端缓慢过滤

时间:2015-06-03 00:44:07

标签: mysql alias

使用MySQL 5.6我在使用int语法条件对计算公式进行过滤时会遇到严重的性能问题。

这个SQL公式由Hibernate映射。 数据库中大约6000行 表格CASE WHEN THEN ELSE END包含列fooproduct

的索引

1。慢2-16秒

barcode

select count(*) from foo AS f where ( CASE WHEN f.product IS NOT NULL THEN 1 ELSE ( CASE WHEN f.barcode IS NULL THEN 0 ELSE ( SELECT EXISTS( SELECT 1 FROM product AS p WHERE p.barcode = f.barcode LIMIT 1 ) ) END ) END ) = 0 结果:

EXPLAIN

2。快〜0.4秒

+----+--------------------+-------+------+-------------------------------+-----+---------+-----+-------+---------------------------------------------------+
| id |    select_type     | table | type |         possible_keys         | key | key_len | ref | rows  |                       Extra                       |
+----+--------------------+-------+------+-------------------------------+-----+---------+-----+-------+---------------------------------------------------+
|  1 | PRIMARY            | f     | ALL  |                               |     |         |     |   700 | Using where                                       |
|  3 | DEPENDENT SUBQUERY | p     | ALL  | UQ_product,IX_product_barcode |     |         |     |  3134 | Range checked for each record (index map: 0x2008) |
+----+--------------------+-------+------+-------------------------------+-----+---------+-----+-------+---------------------------------------------------+

select * from foo AS f where (CASE ... END) = 0 结果与计数查询相同。

1 个答案:

答案 0 :(得分:2)

首先,您应该尝试查看EXPLAIN的输出以获取更多信息。

但无论如何,让我们尝试清理一下您的查询,看看我们是否可以使用一些索引。最大的气味是CASE xxx = 0;我想知道查询解析器是否在制定有效计划时遇到问题,并且每行计算此值并将结果与​​0进行比较。

所以让我们把它重写为:

where f.product is null
and (
    f.barcode is null 
    or exists (select 1 from product p where p.barcode = f.barcode)
)

如果这不能解决问题,请尝试使用ANALYZE TABLE更新索引统计信息。