Reputation: 5544
Using MySQL 5.6 i encounter a big performance problem when filtering on a calculated formula using conditions with CASE WHEN THEN ELSE END
syntax.
This SQL formula is mapped by Hibernate.
Around 6000 rows in database.
Table foo
has indices on columns product
and barcode
1. slow 2-16 s
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
results:
+----+--------------------+-------+------+-------------------------------+-----+---------+-----+-------+---------------------------------------------------+
| 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) |
+----+--------------------+-------+------+-------------------------------+-----+---------+-----+-------+---------------------------------------------------+
2. fast ~ 0.4 s
select
*
from
foo AS f
where
(CASE ... END) = 0
EXPLAIN
results identical to count query.
Upvotes: 1
Views: 1838
Reputation: 116498
First of all you should probably try to look at the output of EXPLAIN
to garner more information.
But either way, let's try cleaning up your query a bit and see if we can't make use of a few indexes. The biggest smell is theCASE xxx = 0
; I wonder if the query parser is having trouble making an efficient plan and is calculating this value per row and comparing the result to 0.
So let's rewrite this as:
where f.product is null
and (
f.barcode is null
or exists (select 1 from product p where p.barcode = f.barcode)
)
If this does not fix the problem, try updating your index statistics with ANALYZE TABLE
.
Upvotes: 2