zoukankan      html  css  js  c++  java
  • mysql分页的问题

    用过mysql的人肯定知道,mysql提供了原生的分页功能-----LIMIT关键字。LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。TIPS:初始记录行的偏移量是 0(而不是 1)。

    但是我再实际的项目过程中使用LIMIT子句时,在分页数目很大的情况下(几万页),后面的翻页的速度明显慢于前面,特别好奇这个现象的原因,于是explain了一下,才发现mysql LIMIT 10000, 20的意思扫描满足条件的10020行,扔掉前面的10000行,返回最后的20行。如下所示:

    EXPLAIN SELECT * FROM exp_platform ORDER BY id DESC LIMIT 10000,5

    ***************** 1. row **************
    id: 1
    select_type: SIMPLE
    table: message
    type: index
    possible_keys: NULL
    key: PRIMARY
    key_len: 4
    ref: NULL
    rows: 10020
    Extra:
    1 row in set (0.00 sec)

    这相当于越往后面翻页越相当于全表扫描,这样在一个高并发的应用下,性能肯定是hold不住的。但是LIMIT n这样的语句性能是没有问题的,因为只扫描n行。于是就想找解决办法,如下:

    Solution1:使用LIMIT n

    "clue法":大概的思路就是在where语句根据id或者别的字段做一些限制。但是这个思路只能提供“上一页”、“下一页”这样的跳转,因为你需要拿到上一页或者下一页的id然后再根据where语句筛选,再使用LIMIT N来做。这样的话,不管翻多少页,每次查询只扫描20行。

    SELECT * FROM exp_platform WHERE id >= 9500 LIMIT 5

    Solution2:使用子查询

    SELECT * FROM exp_platform WHERE id >= (SELECT id FROM exp_platform ORDER BY id LIMIT 10000, 1) LIMIT 20

    子查询是在索引上完成的,而普通查询是在数据文件上完成的,通常来说,索引文件要比数据文件小很多,所以操作起来更有效

    Solution3:使用JOIN分页方式,这个没有尝试过,有机会可以试试。

    实际可以利用类似策略模式的方式去处理分页,比如判断如果是一百页以内,就使用最基本的分页方式,大于一百页,则使用子查询的分页方式。

  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    创建一个最基本的Spring项目
  • 原文地址:https://www.cnblogs.com/babybluevino/p/3936793.html
Copyright © 2011-2022 走看看