MySQL 有where条件时,怎么利用自增ID倒序

发布于 2022-09-11 15:08:34 字数 2656 浏览 19 评论 0

描述

首先有张表, 表结构为

CREATE TABLE `article_like` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `article_id` int(10) unsigned NOT NULL COMMENT '文章id',
  `user_id` int(10) unsigned NOT NULL COMMENT '用户id',
  `create_at` datetime NOT NULL COMMENT '点赞时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_article_id_user_id` (`article_id`,`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='文章点赞表';

一个用户只能对某一篇文章点赞一次,所以对 文章id和用户id 做了唯一索引。

示例数据

图片描述

INSERT INTO `article_like` (`id`, `article_id`, `user_id`, `create_at`) VALUES ('1', '1', '2', '2018-11-06 17:13:24');
INSERT INTO `article_like` (`id`, `article_id`, `user_id`, `create_at`) VALUES ('2', '1', '9', '2018-11-06 17:13:30');
INSERT INTO `article_like` (`id`, `article_id`, `user_id`, `create_at`) VALUES ('3', '1', '7', '2018-11-06 17:13:36');
INSERT INTO `article_like` (`id`, `article_id`, `user_id`, `create_at`) VALUES ('4', '1', '4', '2018-11-06 17:13:46');
INSERT INTO `article_like` (`id`, `article_id`, `user_id`, `create_at`) VALUES ('5', '1', '1', '2018-11-06 17:13:53');
INSERT INTO `article_like` (`id`, `article_id`, `user_id`, `create_at`) VALUES ('6', '1', '10', '2018-11-06 17:14:09');
INSERT INTO `article_like` (`id`, `article_id`, `user_id`, `create_at`) VALUES ('7', '1', '5', '2018-11-06 17:14:28');

不带排序执行查询

SELECT id,article_id,user_id
FROM article_like 
WHERE article_id = 1 
LIMIT 20 

图片描述

SQL 执行如下,可以看到没有安装ID排序了,但是看到 explain 分析是用到了索引,这时候前台要展示点赞列表,但是必须是按最新点赞来排序,所以这个查询满足不了需求

explain 分析

图片描述

用ID排序的查询

SELECT id,article_id,user_id
FROM article_like 
WHERE article_id = 1 
ORDER BY id DESC
LIMIT 20 

图片描述

可以看到现在查询的数据满足需求了,这时候我们来做一次 explain 分析看看,这次发现虽然命中索引,但是用了文件排序。

图片描述

问题来了

这次想要问的是这种场景下这个索引该怎么建立,我现在的思路是建立两个索引,一个是以 文章id 和 用户id 做一个唯一索引,然后在建立一个 单独的以 文章id 做索引,但是这样 MySQL还是会选择 之前那个唯一索引,这个问题很多场景都会用到,如果有知道的同志能不能帮忙解惑一下

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一绘本一梦想 2022-09-18 15:08:34

加个article_id,id,user_id的联合索引

此刻的回忆 2022-09-18 15:08:34
SELECT id,article_id,user_id
FROM article_like 
WHERE article_id = 1 
ORDER BY id DESC
LIMIT 20 

这个查询里使用了article_id 所以Mysql选择了uniq_article_id_user_id这个索引,但是这个索引里并没有包含id,所以order by 不会使用索引,你可以尝试把id也加入索引的第一项,这样可以where语句与ORDER BY语句组合满足最左前缀,就会使用你的索引了。

CREATE TABLE `article_like` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `article_id` int(10) unsigned NOT NULL COMMENT '文章id',
  `user_id` int(10) unsigned NOT NULL COMMENT '用户id',
  `create_at` datetime NOT NULL COMMENT '点赞时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_article_id_user_id` (`id`,`article_id`,`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COMMENT='文章点赞表';


图片描述

盗心人 2022-09-18 15:08:34

试下在表名后加上FORCE INDEX(PRIMARY)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文