2017-07-27 67 views
0

这种MySQL-Query此刻很慢。这种慢MySQL查询的最佳索引是什么? (InnoDB)

这会加速它的最佳指数是什么? (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 

非常感谢!

此致敬礼!

+3

我的第一个倾向是无望的。我认为你的查询必须处理大量数据,这是必要的。 –

+0

目前有哪些指数? – Uueerdo

+0

我已经有数字,item_id,last_calc,bottomlimit和条件的单一索引。 我不确定创建组别indicie会不会更好。 – Webbox

回答

0

我倾向于同意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 
+0

谢谢,我试过这个,但奇怪的是 - 这个表运行之前用MyISAM比InnoDB更快地运行 - 这是正常的吗? – Webbox

+0

您是否缩小了'key_buffer_size'并增加了'innodb_buffer_pool_size'? –

0

你只希望使用索引是为了在一个更简单和索引查询的UNION中打破复杂查询。 首先,你可以使用FROM [子查询]语法

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 

请给我一个反馈在结果上。谢谢。

0

感谢您的帮助!

对我来说最好的解决方案是测试一切后将表转换为MyISAM。

有了这个变化,我可以加快查询速度3到5倍 - 从约12秒到少于3秒。

+0

如果你增加了'innodb_buffer_pool_size',那么你就不需要转换任何东西,并且可以获得与MyISAM相同或更好的性能。 – Mjh

相关问题