程序中翻页查询,你真的懂吗?

  程序员代码的编写能力主要体现在思维的严谨上。有些看起来很简单的东西,里面包含很多很细的点,你能想到吗?

  今天我就简单说一下一个例子,让大家学习到新知识的同时,也养成一种思维的习惯。

问题

  有一张收藏表,里面存储的是用户和图书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 |
+----+---------------+------------+-------+-----------------+-----------------+---------+----------+----------+-------------+

  

推荐

  

时间: 2024-08-07 16:40:45

程序中翻页查询,你真的懂吗?的相关文章

Mvc 翻页查询,代码很有用

Model里的代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Mvc翻页查询.Models { public class CarBF { private masterDataContext _Context = new masterDataContext(); public List<Car> Select(int pageSize,int pag

7.PL_SQL——在PL_SQL程序中内嵌查询语句、DML语句和事物处理语句

在PL/SQL中可以使用的SQL语句主要有以下几类: SELECT 查询语句,DML语句,Transaction 事物处理语句,本文将对这几类语句在PL/SQL中的用法逐一介绍. 一.查询语句-SELECT SELECT 语句用来查询一条或多条语句.虽然SELECT 语句也属于DML语句,但SELECT是只读的,所以单独列出. 在PL/SQL中使用SELECT 语句的格式如下:   SELECT select_list INTO {variable_name[,variable_name]...

c#程序中使用&quot;like“查询access数据库查询为空的问题

今天,在开发的过程中发现了一个特别奇怪的问题:access中like查询时候,在Access数据库中执行,发现可以查询出结果,这是在数据库上执行,select * from KPProj where KpName like '*测试*',但是同样的语句在c#程序中却查询为空,这是什么情况呢? 这个问题真让人纠结,通过以前的开发经验,access中like需要用*号,但是sqlserver oracle数据库中要用标准的%,为什么此时就不行呢?经过搜索资料,最后发现是连接access驱动程序的问题

【tool】软件测试中翻页功能测试用例设计

翻页功能我们常碰到的一般有以下几个功能: 1.首页.上一页.下一页.尾页. 2.总页数,当前页数 3.指定跳转页 4.指定每页显示条数 当然,有一些是少于多少页,全部以数字的形式显示,多于多少页后,才出现下一页的控件.本文暂且用以上四点来做为通用的用例来设计吧. 对于1翻页链接或按钮的测试,主要要检查的测试点有: 1.有无数据时控件的显示情况 2.在首页时,首页和上一页是否能点击 3.在尾页时,下一页和尾页是否能点击 4.在非首页和非尾页时,四个按钮功能是否正确 5.翻页后,列表中的记录是否仍按

Webform 翻页查询.最主要理解这一句代码 return _Context.ChinaStates.Skip((nowpage - 1) * numbers).Take(numbers).ToList();

查询里的方法 using System; using System.Collections.Generic; using System.Linq; using System.Web; /// <summary> /// CarBF 的摘要说明 /// </summary> public class CarBF { private DataClassesDataContext _Context; public CarBF() { _Context = new DataClassesD

MySql翻页查询

分页查询在网页中随处可见,那原理是什么呢?下面简单介绍一下基于MySql数据库的limit实现方法. 首先明确为什么要使用分页查询,因为数据庞大,查询不可能全部显示在页面上,如果全部显示在页面上,也会造成查询速度慢的情况,所以分页查询解决了①数据查询:②性能优化,等(其他问题欢迎补充)的问题. 分页查询也分为真分页和假分页: 真分页:基于数据库查出的数据直接分页显示,优点是改变数据库数据不会影响查询结果,缺点是速度稍慢. 假分页:将所有数据查询出的数据,封装到list集合缓存中,表现层方法调用执

解决Asp.net中翻页问题的自定义用户控件

阿里妹导读:以深度学习为代表的人工智能在图像.语音和NLP领域带来了突破性的进展,在信息检索和个性化领域近几年也有不少公开文献,比如wide& deep实现了深度模型和浅层模型的结合,dssm用于计算语义相关性,deepfm增加了特征组合的能力,deep CF用深度学习实现协同过滤,rnn recommender 采用行为序列预估实现个性化推荐等. 工业级的信息检索或个性化系统是一个复杂的系统工程,深度学习的工业级应用需要具备三个条件:强大的系统计算能力,优秀的模型设计能力和合适的应用场景.今天

Linux文档中翻页和搜索关键字

按键 进行工作空格键 向下翻一页[Page Down] 向下翻一页[Page Up] 向上翻一页[Ctrl + U] 向上翻一页[Ctrl + D] 向下翻一页/string 向下搜寻string这个字符串?string 向上搜寻string这个字符串n,N 搜索字符串时,用n来继续搜索下一个,N来进行反向搜索下一个q 结束Shift + GG         回到文本最底部 原文地址:https://www.cnblogs.com/liuruilongdn/p/10383716.html

easyui grid中翻页多选方法

<table class="easyui-datagrid" title="人员选择" id="dg" data-options="singleSelect:false,toolbar:'#toolbar',pagination:false,fit:true, onSelect:function(rowIndex,rowData){ var iflag=0; if(selceids.length<1){ selceids.p