千万级数据深分页查询SQL性能优化实践-京东零售技术团队

一、系统介绍和问题描述

如何在Mysql中实现上亿数据的遍历查询?先来介绍一下系统主角:关注系统,主要是维护京东用户和业务对象之前的关注关系;并对外提供各种关系查询,比如查询用户的关注商品或店铺列表,查询用户是否关注了某个商品或店铺等。但是最近接到了一个新需求,要求提供查询关注对象的粉丝列表接口功能。该功能的难点就是关注对象的粉丝数量过多,不少店铺的粉丝数量都是千万级别,并且有些大V粉丝数量能够达到上亿级别。而这些粉丝列表数据目前全都存储在Mysql库中,然后通过业务对象ID进行分库分表,所有的粉丝列表数据分布在16个分片的256张表中。同时为了方便查询粉丝列表,同一个业务对象的所有粉丝都会路由到同一张表中,每个表的数据量都能够达到 2 亿+。

二、解决问题的思路和方法

数据库表结构示例如下:

CREATE TABLE follow_fans_[0-255](id bigint(11) NOT NULL AUTO_INCREMENT COMMENT '自增id',biz_content   VARCHAR(50) DEFAULT NULL COMMENT '业务对象ID',source        VARCHAR(50) DEFAULT NULL COMMENT '来源',pin           VARCHAR(50) DEFAULT NULL COMMENT '用户pin',ext           VARCHAR(5000) DEFAULT NULL COMMENT '扩展信息',status        TINYINT(2) DEFAULT 1 COMMENT '状态,0是失效,1是正常',created_time  DATETIME DEFAULT NULL COMMENT '创建时间',modified_time DATETIME DEFAULT NULL COMMENT '修改时间',PRIMARY KEY(id),UNIQUE INDEX uniq_biz_content_pin (biz_content, pin))ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8 COMMENT = '关注粉丝表';

Limit实现

由于同一个业务对象的所有粉丝都保存到一张数据库表中,对于分页查询列表接口,首先想到的就是用limit实现,对于粉丝数量很少的关注对象,查询接口性能还不错。但是随着关注对象的粉丝数量越来越多,接口查询性能就会越来越慢。后来经过接口压测,当业务对象粉丝列表数量达到几十万级别的时候,查询页码数量越大,查询耗时越多。limit深分页为什么会变慢?这就和sql的执行计划有关了,limit语句会先扫描offset+n行,然后再丢弃掉前offset行,返回后n行数据。也就是说limit 100000,10,就会扫描100010行,而limit 0,10,只扫描10行。查询 sql 示例如下:

select  id,biz_content,pin FROM follow_fans_1 where biz_content = #{bizContent} order by id desc limit 10, 10;

•方案优点:实现简单,支持跳页查询。

•方案缺点:数据量变大时,随着查询页码的深入,查询性能越来越差。

标签记录法

Limit深分页问题的本质原因就是:偏移量(offset)越大,mysql就会扫描越多的行,然后再抛弃掉,这样就导致查询性能的下降。所以我们可以采用标签记录法,就是标记一下上次查询到哪一条了,下次再来查的时候,从该条开始往下扫描。具体做法方式是,查询粉丝列表中按照自增主键ID倒序查询,查询结果中返回主键ID,然后查询入参中增加maxId参数,该参数需要透传上一次请求粉丝列表中最后一条记录主键ID,第一次查询时可以为空,但是需要查询下一页时就必传。最后根据查询时返回的行数是否等于 10 来判断整个查询是否可以结束。优化后的查询sql参考如下:

select id,biz_content,pin FROM follow_fans_1 where biz_content = #{bizContent} and id < #{lastId} order by id desc limit 10;

•方案优点:避免了数据量变大时,页码查询深入的性能下降问题;经过接口压测,千万级数据量时,前 N-1页查询耗时可以控制在几十毫秒内。

•方案缺点:只能支持按照页码顺序查询,不支持跳页,而且仅能保证前 N-1 页的查询性能;如果最后一页的表中行数量不满 10 条时,引擎不知道何时终止查询,只能遍历全表,所以当表中数据量很大时,还是会出现超时情况。

区间限制法

标签记录法最后一页查询超时就是因为不知道何时终止查询,所以我们可以提供一个区间限制范围来告诉引擎查询到此结束。

查询sql再次优化后参考如下:

select id,biz_content,pin FROM follow_fans_1 where biz_content = #{bizContent} and id < #{lastId} and id >={minId} order by id desc limit 10;

由于查询时需要带上 minId 参数,所以在执行查询粉丝列表之前,我们就需要先把 minId 查询出来,查询 sql 参考如下:

select min(id) from follow_fans_1 where biz_content = #{bizContent}

由于表中数据量太大,每个表中总数据量都是上亿级别,导致第一步查询 minId就直接超时了,根本没有机会去执行第二步。但是考虑到上一个查询方案只有最后一页才会查询超时,前N-1页查询根本用不到 minId 作为区间限制。所以当表中数据量很大时,通常从第一页到最后一页查询之间会存在一定的时间差。我们就可以正好去利用这个时间差去异步查询minId,然后将查询出来的minId存储到缓存中,考虑到这个 minId 可能会被删除,可以设置一定的过期时间。最后优化后的查询流程如下:

1.调用查询粉丝列表方法时首先查询缓存minId;

2.如果缓存minId 为空,则创建异步任务去执行select min(id) 查询表中的 minId,然后回写缓存,该异步任务执行时间可能会很长,可以单独设置超时时间。

3.如果缓存minId不为空,则在查询sql中拼接查询条件id >={minId},从而保证查询最后一页时不会超时。

但是在上述方案中,如果表中的数据量达到上亿级别时,第二步的异步获取minId任务还是会存在超时的风险,从而导致查询最后一页粉丝列表出现超时。所以我们又引入了离线数据计算任务,通过在大数据平台离线计算获取每个biz_content下的minId,然后将计算结果minId推送到缓存中。为了保证minId能够及时更新,我们可以自由设置该离线任务的执行周期,比如每周执行一次。通过大数据平台的离线计算minId,从而大大减少了在查询粉丝列表时执行 select min(id)的业务数据库压力。只有当缓存没有命中的时候才去执行 select min(id),通常这些缓存没有命中的 minId 也都是一些被离线任务遗漏的少量数据,不会影响接口的整体查询性能。

•方案优点:避免了数据量变大时,页码查询深入的性能下降问题;经过接口压测,千万级数据量时,从第一页到最后一页都控制在几十毫秒内。

•方案缺点:只能支持按照页码顺序和主键ID倒序查询,不支持跳页查询,并且还需要依赖大数据平台离线计算和额外的缓存来存储 minId。

三、对SQL优化治理的思考

通过对以上三种方案的探索实践,发现每一种方案都有自己的优缺点和它的适用场景,我们不能脱离实际业务场景去谈方案的好坏。所以我们要结合实际的业务环境以及表中数据量的大小去综合考虑、权衡利弊,然后找到更适合的技术方案。以下是总结的几条SQL优化建议:

查询条件一定要有索引

索引主要分为两大类,聚簇索引和非聚簇索引,可以通过 explain 查看 sql 执行计划判断查询是否使用了索引。

聚簇索引 (clustered index):聚簇索引的叶子节点存储行记录,InnoDB必须要有且只有一个聚簇索引:

1.如果表定义了主键,则主键索引就是聚簇索引;

2.如果没有定义主键,则第一个非空的唯一索引列是聚簇索引;

3.如果没有唯一索引,则创建一个隐藏的row-id列作为聚簇索引。主键索引查询非常快,可以直接定位行记录。

非聚簇索引 (secondary index):InnoDB非聚簇索引的叶子节点存储的是行记录的主键值,而MyISAM叶子节点存储的是行指针。 通常情况下,需要先遍历非聚簇索引获得聚簇索引的主键ID,然后在遍历聚簇索引获取对应行记录。

正确使用索引,防止索引失效

可以参考以下几点索引原则:

1.最左前缀匹配原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如 a=1 and b=2 and c>3 and d=4 ,如果建立了(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a、b、d的顺序可以任意调整。

2.=和in可以乱序,比如 a=1 and b=2 and c=3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮助优化成索引可以识别的形式。

3.尽量选择区分度高德列作为索引,区分度公式count(distinct col)/count(*),表示字段不重复的比例。

4.索引列不能使用函数或参与计算,不能进行类型转换,否则索引会失效。

5.尽量扩展索引,不要新建索引。

减少查询字段,避免回表查询

回表查询就是先定位主键值,在根据主键值定位行记录,需要扫描两遍索引。 解决方案:只需要在一颗索引树上能够获取SQL所需要的所有列数据,则无需回表查询,速度更快。可以将要查询的字段,建立到联合索引里去,这就是索引覆盖。查询sql在进行explain解析时,Extra字段为Using Index时,则触发索引覆盖。没有触发索引覆盖,发生了回表查询时,Extra字段为Using Index condition。

作者:京东零售交易研发 曹志飞

来源:京东零售技术 转载请注明来源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/666076.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

贪心算法中关于重叠区间问题的感悟

在我这两天的感受中&#xff0c;对区间的排序是解题的关键&#xff0c;能够正确的排序就成功三分之一了。不过想到排序的方法很重要&#xff0c;有的是按照开始点从小到大排列&#xff0c;有的是按照从大到小&#xff0c;有的是按照结束节点排序&#xff0c;有的甚至再排过开始…

[晓理紫]CCF系列会议截稿时间订阅

关注{晓理紫|小李子}&#xff0c;每日更新CCF系列会议信息&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持&#xff01;&#xff01; 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新会议信息。 SAC (CCF C) Select…

物流平台架构设计与实践

随着电商行业的迅猛发展&#xff0c;物流行业也得到了极大的发展。从最初的传统物流到现在的智慧物流&#xff0c;物流技术和模式也在不断的更新与升级。物流平台作为连接电商和物流的重要媒介&#xff0c;其架构设计和实践显得尤为重要。 一、物流平台架构设计 1. 前端架构设…

VSCode Vue 必备插件

VSCode Vue 插件 1. Vue Language Features(Volar)官方插件 volar不仅支持 Vue3 语言高亮、语法检测&#xff0c;还支持 TypeScript 和基于 vue-tsc 的类型检查功能。需要注意的是&#xff1a;使用时需要禁用 Vetur 插件,Volar与它会有冲突 2. Vue VSCode Snippets 此插件为…

京东广告算法架构体系建设--高性能计算方案最佳实践 | 京东零售广告技术团队

1、前言 推荐领域算法模型的在线推理是一个对高并发、高实时有较强要求的场景。算法最初是基于Wide & Deep相对简单的网络结构进行建模&#xff0c;容易满足高实时、高并发的推理性能要求。但随着广告模型效果优化进入深水区&#xff0c;基于Transformer用户行为序列和Att…

OpenSSL:configure: error: OpenSSL library not found解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

项目02《游戏-05-开发》Unity3D

基于 项目02《游戏-04-开发》Unity3D &#xff0c; 【任务】UI背包系统&#xff0c; 首先将Game窗口设置成1920 * 1080&#xff0c; 设置Canvas的缩放模式&#xff0c;&#xff1a;这样设置能让窗口在任意分辨率下都以一个正确的方式显示&#xff0c; 设置数值&…

Mac安装Homebrew+MySQL+Redis+Nginx+Tomcat等

Mac安装HomebrewMySQLRedisNginxTomcat等 文章目录 Mac安装HomebrewMySQLRedisNginxTomcat等一、Mac安装Mysql 8①&#xff1a;下载②&#xff1a;安装③&#xff1a;配置环境变量④&#xff1a;外部连接测试 二、Mac安装Redis和可视化工具①&#xff1a;安装Redis01&#xff1…

【Linux系统 01】Vim工具

目录 一、Vim概述 1. 文件打开方式 2. 模式切换 二、命令模式 1. 移动与跳转 2. 复制与粘贴 3. 剪切与撤销 三、编辑模式 1. 插入 2. 替换 四、末行模式 1. 保存与退出 2. 查找与替换 3. 分屏显示 4. 命令执行 一、Vim概述 1. 文件打开方式 vim 文件路径&#…

美国纳斯达克大屏怎么投放:投放完成需要多长时间-大舍传媒Dashe Media

陕西大舍广告传媒有限公司&#xff08;Shaanxi Dashe Advertising Media Co., Ltd&#xff09;&#xff0c;简称大舍传媒&#xff08;Dashe Media&#xff09;&#xff0c;是纳斯达克在中国区的总代理&#xff08;China General Agent&#xff09;。与纳斯达克合作已经有八年的…

MySQL基础查询篇(4)-INNER JOIN和OUTER JOIN的区别

MySQL数据库中的INNER JOIN和OUTER JOIN是两种常用的连接查询操作&#xff0c;用于联合多张表中的数据。本文将详细介绍它们的区别和示例用法。 INNER JOIN INNER JOIN&#xff08;内连接&#xff09;是连接查询中最常见的一种方式。它基于两个或多个表之间的共同字段&#x…

将`List<String>`转换为`List<Long>`

将List<String>转换为List<Long> 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在Java中&#xff0c;将List<String>转换为List<Long>可以…

ChatGPT实战100例 - (15) 还不会写 Stable Diffusion (SD) 绘画提示词?没关系,ChatGPT帮你搞定

文章目录 ChatGPT实战100例 - (15) 还不会写 Stable Diffusion (SD) 绘画提示词&#xff1f;没关系&#xff0c;ChatGPT帮你搞定一、把场景描述转为镜头语言二、把镜头语言转换为Prompt三、把Prompt转换为图片 ChatGPT实战100例 - (15) 还不会写 Stable Diffusion (SD) 绘画提示…

速盾:免备案网站服务器接入cdn有哪些好处

接入CDN对免备案网站服务器来说有以下几个好处&#xff1a; 提高网站的访问速度&#xff1a;CDN会将网站的静态资源&#xff08;如图片、文档等&#xff09;缓存到离用户最近的节点服务器上&#xff0c;用户访问时可以从离他们最近的节点服务器获取资源&#xff0c;加快访问速度…

微端服务器都需要哪些配置?

微端服务器主要用于大型的网络游戏&#xff0c;可以会游戏用户提供流畅的网速&#xff0c;提高游戏用户的游戏体验感&#xff0c;那么微端服务器配置都有哪些呢&#xff1f; 微端服务器在配置方面是可以根据企业的需求来进行调整&#xff0c;微端服务器主要的核心组件有CPU&…

探秘Java 8 Lambda:简洁高效的集合操作

大家好&#xff0c;欢迎来到今天的播客节目&#xff01;我是你们的主持人&#xff0c;也是一位资深的软件开发者。在今天的节目中&#xff0c;我们将一起深入探讨Java 8中Lambda表达式的妙用&#xff0c;结合实例演示&#xff0c;帮助大家更好地理解并应用于实际的软件开发中。…

24.云原生ArgoCD高级之钩子

云原生专栏大纲 文章目录 Argo CD钩子如何定义钩子钩子删除策略 Argo CD钩子 Argo CD 是一个用于部署和管理 Kubernetes 应用程序的工具&#xff0c;它提供了一种声明式的方式来定义和自动化应用程序的部署过程。Argo CD 钩子&#xff08;Hooks&#xff09;是一种机制&#x…

历年地震数据,shp格式,含时间、位置、类型、震级等信息

基本信息. 数据名称: 历年地震数据 数据格式: Shp 数据时间: 2023年 数据几何类型: 点 数据坐标系: WGS84坐标系 数据来源&#xff1a;网络公开数据 数据字段&#xff1a; 序号字段名称字段说明1dzlx地震类型2zj震级3zysd震源深度&#xff08;米&#xff09;4jtwz…

HDMI2.1之eARC简介-Dolby Atmos和DTS:X

文章目录 eARC目的更大的带宽更高质量音频支持对象型音频与CEC&#xff08;Consumer Electronics Control&#xff09;的兼容性&#xff1a; 适应流媒体发展Dolby AtmosDTS:X高分辨率音频更高的音频位深度和采样率低延迟音频 对象型音频格式独立对象三维定位动态音场适应性和灵…