繁体   English   中英

这种慢速MySQL查询的最佳索引是什么? (InnoDB的)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM