首页 > 数据库 >mysql大数据量的分页慢优化

mysql大数据量的分页慢优化

时间:2023-11-23 09:23:35浏览次数:35  
标签:__ CODE 分页 AREA T1 数据量 mysql label NAME

例子

这边通过一张40w条记录的表来说明一下优化大数据量表分页慢的思路

表单自带拼接语句

SELECT
    tbPage.* 
FROM
    (
    SELECT
        tbTemp.*,
        row_number() over ( ORDER BY ID )- 1 AS rownum__ 
    FROM
        (
        SELECT
            __T1.ID AS ID,
            __T1.NAME AS NAME,
            __T1.SEX AS SEX,
            a0.label AS SEX__label,
            __T1.BIRTHDAY AS BIRTHDAY,
            __T1.IS_DIFFICULTY AS IS_DIFFICULTY,
            __T1.PHONE AS PHONE,
            __T1.AREA_CODE AS AREA_CODE,
            a1.label AS AREA_CODE__label,
            __T1.THREATEN AS THREATEN,
            __T1.GROUP_NAME AS GROUP_NAME,
            __T1.RESPONSIBLE AS RESPONSIBLE,
            __T1.LEAVE_SIGNAL AS LEAVE_SIGNAL,
            __T1.LEAVE_WAY AS LEAVE_WAY,
            __T1.RESETTLEMENT_SITE AS RESETTLEMENT_SITE,
            __T1.REMARK AS REMARK 
        FROM
            tb_person __T1
            LEFT JOIN ( SELECT text AS label, VALUE AS VALUE FROM ss_sys_dic WHERE TYPE = '10007' ) a0 ON __T1.SEX = a0.
            
        VALUE
            LEFT JOIN ( SELECT AREA_NAME AS label, AREA_CODE AS VALUE FROM ss_sys_area ) a1 ON __T1.AREA_CODE = a1.
        VALUE
            
        ) tbTemp 
    WHERE
        1 = 1 
        AND AREA_CODE LIKE CONCAT( '', '', '%' ) 
    ) tbPage 
WHERE
    rownum__ BETWEEN 391930 
    AND 391939

 

Where条件内放

select
  *
from
  (
    SELECT
            __T1.ID AS ID,
            __T1.NAME AS NAME,
            __T1.SEX AS SEX,
            a0.label AS SEX__label,
            __T1.BIRTHDAY AS BIRTHDAY,
            __T1.IS_DIFFICULTY AS IS_DIFFICULTY,
            __T1.PHONE AS PHONE,
            __T1.AREA_CODE AS AREA_CODE,
            a1.label AS AREA_CODE__label,
            __T1.THREATEN AS THREATEN,
            __T1.GROUP_NAME AS GROUP_NAME,
            __T1.RESPONSIBLE AS RESPONSIBLE,
            __T1.LEAVE_SIGNAL AS LEAVE_SIGNAL,
            __T1.LEAVE_WAY AS LEAVE_WAY,
            __T1.RESETTLEMENT_SITE AS RESETTLEMENT_SITE,
            __T1.REMARK AS REMARK 
        FROM
            (select * from tb_person where
  1 = 1  AND AREA_CODE LIKE CONCAT('', '', '%')   order by ID LIMIT  391920, 10) __T1
            LEFT JOIN ( SELECT text AS label, VALUE AS VALUE FROM ss_sys_dic WHERE TYPE = '10007' ) a0 ON __T1.SEX = a0.
            
        VALUE
            LEFT JOIN (
            SELECT
                AREA_NAME AS label,
                AREA_CODE AS 
            VALUE
                
            FROM
                ss_sys_area ) a1 on __T1.AREA_CODE = a1.value 
  ) tbTemp

利用"连接+索引"方式查询

select
  *
from
  (
    SELECT
            __T1.ID AS ID,
            __T1.NAME AS NAME,
            __T1.SEX AS SEX,
            a0.label AS SEX__label,
            __T1.BIRTHDAY AS BIRTHDAY,
            __T1.IS_DIFFICULTY AS IS_DIFFICULTY,
            __T1.PHONE AS PHONE,
            __T1.AREA_CODE AS AREA_CODE,
            a1.label AS AREA_CODE__label,
            __T1.THREATEN AS THREATEN,
            __T1.GROUP_NAME AS GROUP_NAME,
            __T1.RESPONSIBLE AS RESPONSIBLE,
            __T1.LEAVE_SIGNAL AS LEAVE_SIGNAL,
            __T1.LEAVE_WAY AS LEAVE_WAY,
            __T1.RESETTLEMENT_SITE AS RESETTLEMENT_SITE,
            __T1.REMARK AS REMARK 
        FROM
            (select b.* from (
SELECT id from tb_person where
  1 = 1  AND AREA_CODE LIKE CONCAT('', '', '%')   order by ID LIMIT  391920, 10
) a left join tb_person b on a.id = b.id) __T1
            LEFT JOIN ( SELECT text AS label, VALUE AS VALUE FROM ss_sys_dic WHERE TYPE = '10007' ) a0 ON __T1.SEX = a0.
            
        VALUE
            LEFT JOIN (
            SELECT
                AREA_NAME AS label,
                AREA_CODE AS 
            VALUE
                
            FROM
                ss_sys_area ) a1 on __T1.AREA_CODE = a1.value 
  ) tbTemp

 

优化思路

  • 搜索的条件需要加上索引,并且不要做外键label查询这种需求,一定要把查询条件内放到大表的where条件中去
  • 需要使用 带分页sql 功能来重写列表查询语句
  • Mysql的limit语句的查询时间与起始记录的位置成正比即分页的页码越大,查询效率越低,利用表的覆盖索引来加速分页查询:我们都知道,利用了索引查询的语句中如果只包含了那个索引列(覆盖索引),那么这种情况会查询很快。因为利用索引查找有优化算法,且数据就在查询索引上面,不用再去找相关的数据地址了,这样节省了很多时间。另外Mysql中也有相关的索引缓存,在并发高的时候利用缓存就效果更好了。(一句话概括 主分页语句的列只包含主键就好了
    在我们的例子中,我们知道id字段是主键,自然就包含了默认的主键索引。
  • 使用连接+索引方式进行查询

如 :

select b.* from (
SELECT id from tb_person where
  1 = 1  AND AREA_CODE LIKE CONCAT('', '', '%')   order by ID LIMIT  391920, 10
) a left join tb_person b on a.id = b.id

 

 就比

select * from tb_person where
  1 = 1  AND AREA_CODE LIKE CONCAT('', '', '%')   order by ID LIMIT  391920, 10

快很多

优化写法

select
  *
from
  (
    SELECT
            __T1.ID AS ID,
            __T1.NAME AS NAME,
            __T1.SEX AS SEX,
            a0.label AS SEX__label,
            __T1.BIRTHDAY AS BIRTHDAY,
            __T1.IS_DIFFICULTY AS IS_DIFFICULTY,
            __T1.PHONE AS PHONE,
            __T1.AREA_CODE AS AREA_CODE,
            a1.label AS AREA_CODE__label,
            __T1.THREATEN AS THREATEN,
            __T1.GROUP_NAME AS GROUP_NAME,
            __T1.RESPONSIBLE AS RESPONSIBLE,
            __T1.LEAVE_SIGNAL AS LEAVE_SIGNAL,
            __T1.LEAVE_WAY AS LEAVE_WAY,
            __T1.RESETTLEMENT_SITE AS RESETTLEMENT_SITE,
            __T1.REMARK AS REMARK 
        FROM
            (select b.* from (
SELECT id from tb_person where
  1 = 1 {{__where}} {{__order}} LIMIT  #{__page_begin}, #{__page_size}
) a left join tb_person b on a.id = b.id ) __T1
            LEFT JOIN ( SELECT text AS label, VALUE AS VALUE FROM ss_sys_dic WHERE TYPE = '10007' ) a0 ON __T1.SEX = a0.
            
        VALUE
            LEFT JOIN (
            SELECT
                AREA_NAME AS label,
                AREA_CODE AS 
            VALUE
                
            FROM
                ss_sys_area ) a1 on __T1.AREA_CODE = a1.value 
  ) tbTemp
[分割符]
select
  count(*)
from
  tb_person
where
  1 = 1 {{__where}}

 

标签:__,CODE,分页,AREA,T1,数据量,mysql,label,NAME
From: https://www.cnblogs.com/privateLogs/p/17850808.html

相关文章

  • 05MYSQL
    python操作MySQLpython中支持操作MySQL的模块很多其中最常见的当属'pymysql'#属于第三方模块pip3installpymysql(需要安装,可以直接在pycharm中打出来,然后会提示安装)#基本使用importpymysql#1.链接服务端淡黄色表示必须要写的前戏conn_obj=pymysql.......
  • centos7安装MySQL—以MySQL5.7.30为例
    centos7安装MySQL—以MySQL5.7.30为例本文以MySQL5.7.30为例。官网下载进入MySQL官网:https://www.mysql.com/点击DOWNLOADS点击链接;点击如上链接:选择对应版本:点击下载。安装将下载后的安装包上传到/usr/local下。卸载删除原有的mariadb,否则可能会报异常查询原有......
  • Linux系统下进入Mysql
    1、首先查看是否安装mysqlservicemysqldstart2、启动mysql服务systemctlstartmysqld.service 没报错就启动成功。3、查看mysql运行状态servicemysqldstatus出现绿色启动成功!4、进入数据库mysql-uroot-p密码一般为123456也可以输入命令:查看初始密......
  • pgsql 和 mysql语法对比
    超全mysql转换postgresql数据库方案https://blog.csdn.net/weixin_42303757/article/details/128896250?spm=1001.2101.3001.6650.4&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-4-128896250-blog-131395729.235%5Ev38%5Epc_relevant_anti_t......
  • MySQL语句语法练习记录
    导言:MySQL是一种广泛使用的关系型数据库管理系统,掌握MySQL语句的语法对于数据库开发和管理至关重要。本篇博客将记录一些常见的MySQL语句语法练习,并提供相关的演示示例,帮助读者更好地理解和应用MySQL语句。1.创建数据库和表创建数据库和表是开始使用MySQL的第一步。下面是一个创......
  • MySQL 基础介绍
    MySQL介绍相关概念DB(DataBase)数据库。是一个存储数据的容器DBA(DatabaseAdministrator):数据库管理员。负责数据库的管理和维护的专业人员DBMS(DatabaseManagementSystem):数据库管理系统。是一种软件,用于创建和管理数据库。App(Application):应用程序。执行特定任务或一系列任务的......
  • Spring Cloud +UniApp +MySql框架开发的智慧工地云平台源码
    智慧工地是指通过信息化技术、物联网、人工智能技术等手段,对建筑工地进行数字化、智能化、网络化升级,实现对施工全过程的实时监控、数据分析、智能管理和优化调控。智慧工地的建设可以提高工地的安全性、效率性和质量,降低施工成本,是建筑行业数字化转型升级的重要抓手。主要围绕“人......
  • 【jsp】mysql 封装类
    【jsp】mysql封装类大家拿着就能使用  packagebean;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;publicclassDBUtil{static{//MySQL5.7......
  • MySql存储树形结构,Java实现根据节点找到父节点,根据节点找到子节点
    目录数据表设计生成树(递归方式)根据节点cId返回所有的父节点pId数据表设计idparent_idnamelevel10食物121蔬菜231水果242茄果类352叶菜类363浆果类373瓜果类384番茄494辣椒4105生菜4116桑葚4id......
  • MySQL数据类型
    数据类型1.MySQL中的数据类型类型类型举例整数类型TINYINT,SMALLINT,MEDIUMINT,INTBIGINT浮点类型FLOAT,DOUBLE定点数类型DECIMAL位类型BIT日期时间类型YEAR,TIME,DATE,DATETIME,TIMESTAMP文本字符串类型CHAR,VARCHAR,TI......