记一次百万数据量查询sql 优化

  • 问题描述
  • 问题分析过程
  • 总结
    • 简单了解用到的pgsql 的索引结构
    • pgsql 的with
  • 扩展
    • 对于更大数据量的数据还有没有其他更好的方案

问题描述

数据库用的是pgsql。sql 中用到了表连接,group by ,count以及sum 函数,现场测试的时候由于有定时任务在跑,所以数据库中一直有增量。当数据达到200万条时,页面加载时间非常慢,达到40s。

问题分析过程

本人开发小白一个,日常搬砖。之前没有接触过太大数据量的业务,只有面试的时候自己看过相关的sql优化知识,而实践还是头一次。
1.把查询慢的sql提出来,对where条件中的字段加上索引。由于之前开发用的是mysql,对pgsql 的一些特性不是很了解,所以默认的索引结构都是btree。

CREATE INDEX indexname ON tablename (code)
selectcount(retrival.id) retrivalNum,retrival.index_code,retrival.camera_name,province."name" place,sum(end_time-start_time) retrivalDuration,retrival.province_codefromretrivalleft joinresourceonretrival.index_code = resource.index_codeleft joinprovinceonresource.province_code  = province.code    group byretrival.index_code,resource.province_code,retrival.camera_name

2.由于业务比较复杂,涉及到了三个表关联,后来和对接人探讨,最后决定在表中加一个关联字段,以达到少关联一个表的目的。

selectcount(retrival.id) retrivalNum,retrival.index_code,retrival.camera_name,province."name" place,sum(end_time-start_time) retrivalDuration,retrival.province_codefromretrivalleft joinprovinceonretrival.province_code  = province.codewhere position('100000' in province.path) > 0and retrival.camera_name like '%%'AND retrival.start_time >= ''AND retrival.end_time <=  ''group byretrival.index_code,retrival.province_code,retrival.camera_name,province.namelimit 25 index 0

3.对连接表关联到的字段加索引。
4.加完索引之后查询时间并没有得到改善,查询时间还是30s左右,加上分页并没有什么大的影响。
5.这时候我想着尝试不做表关联,将sql拆分,去掉group by ,将逻辑转换到代码中(以为这样会更快)
改完之后测试接口请求,发现在代码中效率也没有得到改善,反而更慢,因为放到代码中分页的优势就没有了。
6.由于项目现场催的比较紧,没有足够的时间去查阅相关资料,所以求助了带我的导师。
7.导师将字段索引分类改成了联合索引,并根据不同的查询条件修改对应的索引结构。这里pgsql 不只有btree一种索引结构。还有brin,gin等,初步了解gin可用到模糊查询(适用于非前缀模糊查询)的字段,brin 是比较,类似于>= <=等。

create extension pg_trgm;
create extension btree_gin; (必须管理员权限执行)
create index indexname on tablename using gin (...)create index indexname on tablename using brin (...) with (pages_per_range=1)   

8.修改联合索引并调整字段顺序之查询时间在15s左右。explain 看sql 执行情况,发现还是group by 上面以及count 函数消耗的时间比较久。group by 后面跟了四个字段。这时候数据量已经达到700万。所以还是需要再优化。
9.导师提出了pgsql 的with 语句,此处,将group by 拆分,在with 中只根据count里面的字段进行统计,此处with 相当于将结果放入内存作为一个临时表。然后再从内存中关联其他需要的字段。这样优化之后分页查询执行时间只需要几百毫秒。

WITH tm AS (SELECT retrival.index_code,COUNT( retrival.index_code ) retrivalNum,SUM ( end_time - start_time ) retrivalDuration
FROMretrivalJOIN province ON retrival.province_code = province.code
WHEREretrival.start_time >= '' AND retrival.end_time <= ''
--  AND retrival.camera_name LIKE'%研%' AND POSITION ( '100000' IN province.PATH ) > 0
GROUP BYretrival.index_code
ORDER BY retrival.index_code
LIMIT 25 OFFSET 0)SELECT distinct retrival.index_code,retrival.province_code ,retrival.camera_name,province."name" place,t.retrivalNum, t.retrivalDurationFROM  retrivalJOIN tm t ON retrival.index_code = t.index_codeJOIN  province ON retrival.province_code = province.codeORDER BY retrival.index_codeLIMIT 25 OFFSET 0

explain 查看

可以看到explain查出来的执行计划中都用到了哪些索引,pgsql 默认是按顺序扫描的,用下面的这个语句可以禁用顺序扫描强制使用索引,执行之后速度更快,控制在100ms左右

SET enable_seqscan = OFF;

总结

简单了解用到的pgsql 的索引结构

BRIN索引:存储关于存储在表的连续物理块范围内的值的摘要,可以使用BRIN索引的特定操作符根据索引策略而变化。对于具有线性排序顺序的数据类型,索引数据对应于每个块范围的列中值的最小值和最大值。这支持使用这些运算符的索引查询:

>=
<=
=

Gin索引是用来加快全文搜索的,适合做模糊查询和正则查询。
btree 和 brin 比较(pgsql 社区有相关演示及介绍):
1.空间上:BRIN相比BTREE索引在空间占用上小很多(数据量千万级时有几千倍之差),在存储空间占用上具备巨大优势。对于数据仓库或者VLDB应用可以节省大量的存储成本。
2.查询上:对于等值的唯一查询,BTREE在性能上有显著优势。但在不同数据分布情况下,BTREE在性能上的领先优势差别非常大,从不到1倍到265倍。
3.在选择创建BRIN还是BTREE索引时,需要权衡性能和空间使用两方面的影响。根据数据量、数据分布和SQL选择最适合的索引类型。在性能相差不大的情况下,选择BRIN可能是更加经济的选择。总体来说,当实际匹配数据量较少时,BTREE索引更加适合;反之,BRIN更加适合。
4.由于BRIN索引的lossy特性,需要消耗较多的CPU时间用于精确匹配。

pgsql 的with

概念:WITH语句通常被称为通用表表达式(Common Table Expressions)或者CTEs。
WITH提供了一种方式来书写在一个大型查询中使用的辅助语句。
可以被看成是定义只在一个查询中存在的临时表。
使用:在WITH子句中的每一个辅助语句可以是一个SELECT、INSERT、UPDATE或DELETE,并且WITH子句本身也可以被附加到一个主语句,主语句也可以是SELECT、INSERT、UPDATE或DELETE。

扩展

对于更大数据量的数据还有没有其他更好的方案

查阅了一下网上资料,关于pgsql 大数据量的查询优化文章还是很多的。此处简单罗列,毕竟需要学习和了解的还很多。希望以后能够结合实际业务都能运用的上。
1.根据一定的条件进行分区(年月日等)
2.增加内存大小
3.根据不同的条件合理的时候相应的索引结构。
4.硬件上的优化支持

记一次百万数据量查询sql 优化相关推荐

  1. 任何抛开业务谈大数据量的sql优化都是瞎扯

    周三去某在线旅游公司面试.被问到了一个关于数据量大的优化问题.问题是:一个主外键关联表,主表有一百万数据,外键关联表有一千万的数据,要求做一个连接. 本人接触过单表数据量最大的就是将近两亿行历史数据( ...

  2. mysql查询单表的销售额_MYsql数据库单表百万数据量查询

    最近总在意自己的网页刷新数据的速度,mysql5.7和mysql8.0单表数据库导入百万甚至千万数据的时候,会不会卡死,会不会慢? 因此编写测试用例,通过Navicat Premium来查询单表的时间 ...

  3. 百万数据量下,使用延迟关联优化超大分页

    百万数据量下,使用延迟关联优化超大分页 MySQL 并不是跳过 offset 行,而是取 offset + N 行,然后返回放弃前 offset 行,返回 N 行,那当offset 特别大的时候,效率 ...

  4. 高并发的大数据量查询导致系统频繁死机

    我们的大数据量查询是数据库分页的, 但是导出和打印功能是基于全部数据的. 系统投入使用后,对于导出和打印功能的使用远远要高于我们的预期. 而我们的系统的硬件设备是有限的 不能再升级了. 抓取内存大对象 ...

  5. Flink流式处理百万数据量CSV文件

    前言 最近公司让做一个'没有必要'的需求 需求针对的对象 这是同一个csv文件的不同展示形式 Excel展示形式 文本展示形式 这个csv文件中可能有数百万条数据 需求 将所有的异常数据检测出来 什么 ...

  6. 百万数据进行查询与排序

    百万数据进行查询与排序! 在网上找了一堆,有一下几大排序算法如:快速排序,归并排序,堆排序,百万数据查询 . 那什么是快速排序: 1.  快速排序算法是一种不稳定的排序算法.其时间复杂度为O(nlog ...

  7. 大数据量查询:流式查询与游标查询

    最近在做一个计算相关的功能,大体就是有很多条SQL,每条SQL都涉及复杂地运算,最后要将所有计算结果进行合并分析.经初步测试,每个SQL起码会查出几十万条记录,我们现在有毛毛多的这种SQL. 最大的问 ...

  8. redis 用scan 代替keys 解决百万数据模糊查询超时问题

    redis 用scan 代替keys 解决百万数据模糊查询超时问题 参考文章: (1)redis 用scan 代替keys 解决百万数据模糊查询超时问题 (2)https://www.cnblogs. ...

  9. Java操作百万数据量Excel导入导出工具类(程序代码教程)

    Java操作百万数据量Excel导入导出工具类(程序代码教程): # 功能实现1.自定义导入数据格式,支持配置时间.小数点类型(支持单/多sheet)(2种方式:本地文件路径导入(只支持xls.xls ...

最新文章

  1. curl: (3) [globbing] error: bad range specification after pos 150的解决方法
  2. Linux epoll
  3. 超实用的 Mybatis 3.5 新特性
  4. nor flash和nand flash
  5. 安全行业最全防火墙产品全家福
  6. Mock生成随机数据常用的类型规则
  7. Oracle数据反向恢复
  8. Robotics正运动学求解仿真(附代码和解释)
  9. Office之word如何删除页眉横线
  10. ContentProvider 之 监听共享数据变化
  11. Win10+1050Ti配置tensorflow-gpu教程 (解决1050ti配置cuda失败的问题)
  12. [2018.11.05 T1] 喝牛奶
  13. AUTOCAD——隔离
  14. JS字符串格式化函数 string.format
  15. Hash表_拉链法_开放寻址法_模拟散列表
  16. 【白皮书分享】2020脱发治疗白皮书.pdf(附下载链接)
  17. 战地一服务器性能低怎么办,《战地1》帧数优化图文攻略 战地1帧数低怎么办?...
  18. ospf避免环路_多进程OSPF发布LSA形成路由环路的规避办法
  19. VB编程:While...Wend语句实例漂亮的星星-17
  20. 机智云代码移植_【机智云Gokit3测评】设备接入-步骤二:程序移植

热门文章

  1. 1.2 行化简和阶梯形矩阵(线性代数及其应用-第5版-系列笔记)
  2. 物流ERP软件测试行业,简单说说ERP测试
  3. python elasticsearch orm_国产elasticsearch orm框架 bboss使用技巧
  4. python请输入用户名编程_Python基础练习之用户登录实现代码分享
  5. 使用Xposed实现QQ/TIM自动确认电脑扫一扫登录
  6. NS4115 1A 内置功率管 LED 恒流驱动器
  7. Python网易云音乐单曲爬取
  8. 华南理工大学计算机辅助设计,《计算机辅助设计》课程教学大纲.PDF
  9. 一款学生党实测好用的美赛论文翻译软件推荐
  10. 软件测试工作是吃青春饭的吗?