使用MySQL 5.6我在使用int
语法条件对计算公式进行过滤时会遇到严重的性能问题。
这个SQL公式由Hibernate映射。
数据库中大约6000行
表格CASE WHEN THEN ELSE END
包含列foo
和product
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
结果与计数查询相同。
答案 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
更新索引统计信息。