mysql – 具有等式[A],范围[B],分组依据[C]和按[count(P)]顺序查询的最佳索引策略
作者:互联网
我的查询效果不佳:
SELECT user_id, count(item_id) as count
FROM table items
WHERE category = 'magazine'
AND created_at > 1384754400
GROUP BY user_id
ORDER BY count(item_id) desc
LIMIT 100
什么是最佳索引策略以优化此查询?
表详细信息
5亿条记录,具有以下结构/基数:
> PRIMARY KEY(item_id) – 基数:500 M.
> user_id – 基数:~25 M.
>类别 – 基数:~2.5 M
> created_at – 基数:~150 M.
索引:
>我在user_id,category和created_at字段中都有各自的索引
我还有以下覆盖索引:
>(category,user_id) – 这是查询优化器在运行explain时默认的那个
>(category,created_at)
>(category,created_at,user_id) – 我试图创建这个以优化此查询,但是,它似乎不能很好地工作.
解决方法:
如果您只想针对此查询进行优化.这是最好的指数:
ALTER TABLE items ADD INDEX (category, created_at, user_id)
这样可以优化过滤器的值,从而减少您触摸的数据总量.通过在查询末尾添加user_id,item_id,可以使索引覆盖,并且可以节省对主索引的查找.
我们可以假设item_id是NOT NULL(因为它是PRIMARY索引).
但是,因为MySQL优化器非常愚蠢,您可能需要像这样重写:
SELECT user_id, SUM(count) AS count
FROM
(
SELECT category, created_at, user_id, COUNT(*) as count
FROM items
WHERE category = 'magazine'
AND created_at > 1384754400
GROUP BY category, created_at, user_id
) AS d
GROUP BY user_id
ORDER BY count DESC
LIMIT 100
标签:query-performance,mysql,mariadb,index-tuning,index 来源: https://codeday.me/bug/20190806/1598789.html