[英]What would be the best indices for this kind of slow MySQL-Query? (InnoDB)
目前,这种MySQL查询非常慢。
加快速度的最佳索引是什么? (InnoDB的)
SELECT item_id,
Group_concat(storage_nr SEPARATOR ',') AS storage_nr,
Group_concat(condition SEPARATOR ',') AS condition,
Group_concat(number SEPARATOR ',') AS number,
Group_concat(price SEPARATOR ',') AS price,
last_calc
FROM items
WHERE number > 0
AND bottomlimit IS NOT NULL
AND condition IN (1, 2, 3)
AND ( price_date IS NULL
OR price_date < Date_sub(Now(), INTERVAL 1 hour) )
AND ( NOT ( price = bottomlimit
AND pricebefore = bottomlimit
AND pricebefore2 = bottomlimit )
OR price IS NULL
OR pricebefore IS NULL
OR pricebefore2 IS NULL
OR Date(price_date) <> Curdate() )
GROUP BY item_id
ORDER BY last_calc
LIMIT 20
在此先多谢!
最好的祝福!
我倾向于在大多数情况下同意Gordon的评论,但是您可以尝试的一件事是条件聚合。 (这可能是独特的情况之一,在这种情况下,处理更多数据并丢弃不需要的数据比过滤到需要的数据要快,尤其是因为某些OR条件似乎会破坏MySQL中的索引使用)。
与此类似的方法可能会有所帮助。
SELECT item_id
, Group_concat(
IF(condition IN (1, 2, 3)
AND ( price_date IS NULL OR price_date < Date_sub(Now(), INTERVAL 1 hour) )
AND ( NOT ( price = bottomlimit AND pricebefore = bottomlimit AND pricebefore2 = bottomlimit )
OR price IS NULL
OR pricebefore IS NULL
OR pricebefore2 IS NULL
OR Date(price_date) <> Curdate()
)
, storage_nr, NULL)
SEPARATOR ','
) AS storage_nr
, [etc...]
FROM items
WHERE number > 0 AND bottomlimit IS NOT NULL
GROUP BY item_id
HAVING storage_nr IS NOT NULL
ORDER BY last_calc
LIMIT 20
您唯一希望使用索引的方法是在更简单的索引查询的UNION中分解复杂的查询。 首先,您可以使用FROM [subquery]语法
SELECT item_id,
Group_concat(storage_nr SEPARATOR ',') AS storage_nr,
Group_concat(condition SEPARATOR ',') AS condition,
Group_concat(number SEPARATOR ',') AS number,
Group_concat(price SEPARATOR ',') AS price,
last_calc
FROM
SUBQUERY
AS items
GROUP BY item_id
ORDER BY last_calc
LIMIT 20
这可能是您的子查询:
SELECT *
FROM items
WHERE number > 0
AND bottomlimit IS NOT NULL
AND condition IN (1, 2, 3)
AND price_date IS NULL
AND ( NOT ( price = bottomlimit
AND pricebefore = bottomlimit
AND pricebefore2 = bottomlimit )
OR price IS NULL
OR pricebefore IS NULL
OR pricebefore2 IS NULL
OR Date(price_date) <> Curdate() )
UNION ALL
SELECT *
FROM items
WHERE number > 0
AND bottomlimit IS NOT NULL
AND condition IN (1, 2, 3)
AND price_date < Date_sub(Now(), INTERVAL 1 hour)
AND ( NOT ( price = bottomlimit
AND pricebefore = bottomlimit
AND pricebefore2 = bottomlimit )
OR price IS NULL
OR pricebefore IS NULL
OR pricebefore2 IS NULL
OR Date(price_date) <> Curdate() )
定义以下索引
- condition
- price_date
- bottomLimit
请给我有关结果的反馈。 谢谢。
感谢您的帮助!
对我来说,最好的解决方案是在测试所有内容后将表转换为MyISAM。
通过此更改,我可以将查询速度提高3到5倍-从大约12秒缩短到不到3秒。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.