有一张收藏表,里面存储的是用户和图书ID。数据量为1亿。现在要求分页获取所有用户ID(不重复),写下你的sql语句。

表结构大致如下:

CREATE TABLE 收藏表(
`id` bigint(20) unsigned NOT NULL auto_increment COMMENT 'primary key',
`uid` bigint(20) unsigned NOT NULL default 0 COMMENT 'uid',  
`status` tinyint(3) unsigned NOT NULL default 0 COMMENT 'status',
`book_id` bigint(20) unsigned NOT NULL default 0 COMMENT 'book Id',
`create_time` int(11) unsigned not null default 0 COMMENT 'create time',
PRIMARY KEY (`id`),
UNIQUE KEY `uid_book_id` (`uid`, `book_id`),   
KEY `uid_status` (`uid`, `status`)
)ENGINED=Innodb Auto_increment=1 default charset=gbk COMMENT '用户收藏信息';

三种设计

最容易想到的第一种分页语句是(这也是我们最容易想到的语句):

select distinct uid from 收藏表 order by uid desc limit 0, 10;
select distinct uid from 收藏表 order by uid desc limit 11, 10;

再高级点语句,第二种($last_min_uid表示上一次读到的最后一个uid):

select distinct uid from 收藏表 order by uid desc limit 10;
select distinct uid from 收藏表 where uid < $last_min_uid order by uid desc limit 10;

最高级的方式

select uid from 收藏表 group by uid order by uid desc limit 10;
select uid from 收藏表 group by uid having uid < $last_min_uid order by uid desc limit 10;

分析

以上三种方式都可以实现分页获取到用户ID列表,那么区别是什么?我现在就把每一种跟大家分析下。

第一种在业务场景中,会出现丢数据的情况。——这是比较严重的情况,不予采纳。

具体的业务场景是这样的:当你读取第5页的时候,前四页的用户id列表中,假如有一页的用户ID从库中删除掉,那么你这时读到的第5页(limit 51, 10),就是原来的第6页,你会把1页的用户ID丢失掉。

第二种的第二条语句,通过explain分析,实际并没有命中唯一索引,而只是命中了一般索引,数据查询范围在7百万级别,故explain建议我们使用group by。——这个查询会有严重的性能问题。

+
----+--------------+---------------+-------+-------------------
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+
----+--------------+---------------+-------+-------------------
| 1 | SIMPLE | ubook_room | range | uid_book_id | uid_status | 4 | NULL | 7066423 | Using where; Using index for group-by; Using temporary; Using filesort |
+
----+--------------+---------------+-------+-------------------

第三种explain分析,数据查询范围在12万级别(跟第二种相差一个数量级),查询性能高。

+
----+--------------+---------------+-------+-------------------
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+
----+---------------+------------+-------+-----------------+-----------------+---------+---
| 1 | SIMPLE | 收藏表 | index | NULL | uid_book_id | 12 | NULL | 121719 | Using index |
+
----+---------------+------------+-------+-----------------+-----------------+---------+---


更多相关文章

  1. 在MySQL数据库中存储无法访问的用户
  2. init-connectMysql对用户操作加审计功能
  3. 一些值得收藏的MySQL知识链接
  4. mysql user表root 用户修改权限后出现无法访问数据库的解决方法
  5. Linux下修改MySQL初始密码、开启远程登录、授权远程登录用户
  6. 保存在Java桌面应用程序应用程序和网站上使用的个人用户设置的最
  7. 是一个mysql临时表,每个用户访问创建它的脚本是唯一的...?
  8. MVC框架——学生信息管理系统(多表,多事务如何处理,一个用户如何共
  9. MySQL5.7以上版本root用户空密码修改(windows系统、zip版MySQL)

随机推荐

  1. 一起学android之给图片添加涂鸦(文字)(37)
  2. Android---2---TextView、Button、EditTe
  3. Android中的android:layout_width和andro
  4. Android菜鸟之路-多线程下载
  5. android中九宫格布局的实现
  6. Android(安卓)studio真的很坑啊,智能还很
  7. android的PowerManager和PowerManager.Wa
  8. Android单元测试 Instrumentation
  9. android View各属性详解
  10. Android应用程序启动过程源代码分析