带组的慢速计数查询

Slow count query with group

我有一个共同的聚合查询:

SELECT 
      products.type, 
      count(products.id) 
   FROM 
      products
         INNER JOIN product_colors 
            ON products.id = product_colors.product_id 
           AND product_colors.is_active = 1 
           AND product_colors.is_archive = 0 
   WHERE 
         (products.is_active = 1 
      AND product_colors.is_individual = 0 
      AND product_colors.is_visible = 1) 
   GROUP BY 
      type 

持续0.1秒左右。索引看起来不错,tmp_table_size = 128M 和 max_heap_table_size = 128M。为什么他们这么慢?经典选择很快,但是因为有组和计数,所以没有。

产品索引table:

索引 product_colors table:

说明SQL:

EDIT 产品索引:

对于您的要求,您的索引不是最佳的。与其只在每一列上单独建立索引(这可能是一种很大的浪费),不如建立复合索引来更好地匹配您要查询的内容,并且覆盖范围足以处理任何分组依据或排序。

在这种情况下,您的主要查询是有效产品和按类型排序。所以我会在 (is_active, type, id) 上的主 table 上有一个 SINGLE 索引。这样,您的 WHERE 标准是通过 Is_Active 预先确定的,然后是通过类型确定的订单,最后是符合记录条件的 ID。在这种情况下,您的查询可以从 INDEX 中获取所需的一切,而不必转到原始数据页面。

现在,你的中学 table。同样应该是复合索引。首先基于 table 之间的连接标准,然后基于您正在寻找的限制,因此:( product_id, is_active, is_archive )。为什么你有两列 Is_Active 和另一列 Is_Archive,不知道。我想如果档案里有什么东西,它一开始就不会活跃,但只是猜测。

无论如何,优化索引应该有所帮助。

最后一次考虑(product.id)。您打算使用 DISTINCT 产品,还是找到所有记录。那么如果一个产品有8种颜色,你想把ID算成1还是8。

count(*) would give 8
count( distinct product.id ) would give 1

试试这些:

products:  INDEX(is_active, type)
product_colors:  INDEX(product_id, is_individual, is_visible,   is_active, is_archive)

既然products.id不能为NULL,你不妨说COUNT(*)而不是count(products.id)。 (或者,正如 DRapp 指出的那样,也许您 需要 COUNT(DISTINCT products.id)