数据库
首页 > 数据库> > mysql – 具有等式[A],范围[B],分组依据[C]和按[count(P)]顺序查询的最佳索引策略

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