带组的慢速计数查询
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)
我有一个共同的聚合查询:
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)