zoukankan      html  css  js  c++  java
  • 上万页大数据量的分页查询方案

    上万页大数据量的分页查询方案

    背景

    数据量:五万页。

    一、方案1

    SELECT
    	* 
    FROM
    	t_view_log AS t 
    ORDER BY
    	t.create_time DESC 
    LIMIT 50000 OFFSET 10;
    
    -- 耗时76秒,不可接受。
    

    create_time字段添加索引后,没有改观,通过分析执行计划,走的全表扫描,因为MySQL预判,在create_time没有条件,故走索引不如全表扫描来的快。

    聚集索引(主键索引是一种聚集索引)和非聚集索引图示:

    二、方案二

    现在,我们要想办法让create_time索引生效,就是create_time成为查询条件。

    SELECT
    	t.* 
    FROM
    	t_view_log AS t 
    WHERE
    	t.create_time >= (
    		SELECT t.create_time FROM t_view_log AS iv ORDER BY iv.create_time DESC LIMIT 50000 OFFSET 1 
    	) 
    ORDER BY
    	t.create_time DESC 
    LIMIT 10;
    
    -- 耗时2秒
    
    1. 先利用索引覆盖,通过子查询,查出第50000条数据的的创建时间

    索引覆盖:查询结果只包含索引字段的查询,将直接从索引结构获取数据,不会反查数据表做扫描,所以效率非常高。

    1. 再利用第50000条的创建时间,作为条件查出10条数据

    三、方案三

    实践中,前端通常是按照上一页 下一页这种方式来查询的,所以可以预先将当前页的首尾两条数据的create_time从前台传入,作为条件,这样就可以避免子查询。

    SELECT
    	t.* 
    FROM
    	t_view_log AS t 
    WHERE
    	t.create_time >= (
    		SELECT t.create_time FROM t_view_log AS iv ORDER BY iv.create_time DESC LIMIT 50000 OFFSET 1 
    	) 
    ORDER BY
    	t.create_time DESC 
    LIMIT 10;
    
    -- 耗时不到1秒
    

    现在很多UI设计,已经不再提供具体的页码供翻页操作了,仅保留首页上一页下一页按钮,包括移动端的下划加载更多数据,都是基于这种思路,这更利于查询优化。同时还能省略COUNT(*)的统计函数。

    在并发场景下,条件数据create_time会出现重复,当出现大量重复时,会导致局部的循环分页,无法前进或后退,此时就需要以页大小作为偏移,才能解决。

    思考:数据页上万后,真的有必要考虑后面的数据分页吗,百分之九十的情况是没人关注后面的数据,关注点往往停留在前几页。所以,从业务上,可以只给用户展示前面的一百页数据,将这块数据做缓存,也就能从业务上规避技术难题了。

  • 相关阅读:
    js 加密混淆工具
    postgresql 相关函数总结
    eclipse启动Tomcat时报错:严重: Exception loading sessions from persistent storage
    java sm4国密算法加密、解密
    java mail 封装工具类使用
    echarts 折线图百分比 tooltip 实例 两种方法
    开启人生的巅峰!!!
    判断是不是谷歌浏览器
    C#导出Excel的具体代码,供大家参考,具体内容请求URL
    SVN 安装后右键出现点击鼠标右键弹出错误提示:CrashHandler initialization error
  • 原文地址:https://www.cnblogs.com/JaxYoun/p/15583983.html
Copyright © 2011-2022 走看看