[ruby on rails] postgres sql explain 优化

一、查看执行计划

sql = User.all.to_sql
# 不会实际执行查询
puts ActiveRecord::Base.connection.explain(sql)# 会实际执行查询,再列出计划
User.all.explain# 会实际执行查询,再列出计划ActiveRecord::Base.connection.execute('EXPLAIN ANALYZE '+ sql).each { |a| pp a }

注意:
在加上 ANALYZE 选项后,会真正执行实际的 SQL,如果 SQL 语句是一个插入、删除、更新或 CREATE TABLE AS 语句,这些语句会修改数据库。为了不影响实际的数据,可以把 EXPLAIN ANALYZE 放到一个事务中,执行完后回滚事务,如下:

BEGIN;
EXPLAIN ANALYZE ...;
ROLLBACK;

节点是从下往上看,上一级节点的成本,是包含了下一级的成本的

pry(#<Goods>)> ActiveRecord::Base.connection.execute('EXPLAIN ANALYZE '+ sql).each { |a| pp a }(4.9ms)  EXPLAIN ANALYZE SELECT "users".* FROM "users"
{"QUERY PLAN"=>"Seq Scan on users  (cost=0.00..67.63 rows=1463 width=587) (actual time=0.056..2.063 rows=1463 loops=1)"}
{"QUERY PLAN"=>"Planning Time: 0.409 ms"}
{"QUERY PLAN"=>"Execution Time: 2.207 ms"}

二、解释

  • cost=0.00…67.63 rows=1463 width=587, 左到右:
  1. 预计启动成本。这是输出阶段开始之前所花费的时间,也就是返回第一行需要多少 cost 值,例如,在排序节点中进行排序的时间。
  2. 预计总成本。这是基于计划节点运行完成的假设,即检索所有可用行。实际上,节点的父节点可能无法读取所有可用行(请参见LIMIT下面的示例)。
  3. rows 该计划节点输出的估计行数。同样,假设该节点已运行完成。
  4. width 该计划节点输出的行的估计平均宽度(以字节为单位)。
  5. buffers
    shared hit:表示在共享内存中直接读到 xxx 个块,
    read:表示从磁盘读了 xxx 块
    written:写磁盘工 xxx 块
    .
    默认 cost 值如下
    顺序扫描一个数据块,cost 值定为 1
    随机扫描一个数据块,cost 值定为 4
    处理一个数据行的 CPU,cost 为 0.01
    处理一个索引行的 CPU,cost 为 0.005
    每个操作符的 CPU 代价为 0.0025

注意: "actual time"数值是以真实时间的毫秒来计算的,而"cost"预估值是以磁盘页面读取数量来计算的,所以它们很可能是不一致的。

三、解释

1. Bitmap Scan

  • Bitmap Scan 扫描的出现是基于获取的数据在 INDEX SCAN 中的问题点而产生的一个数据的获取的方式,在INDEX SCAN 中获取到数据的位置后,还是需要到对应的数据页面中,在扫描到对应的数据,而BITMAP SCAN 就是要解决数据通过索引定位后,在去原数据页面定位的问题,解决最后一公里的问题。
  • 所以通过位图来获取数据的方式,速度更快,当然相对的付出的成本也更多一些。

2. Bitmap Index Scan 与Bitmap Heap Scan

BitmapIndex Scan 与Index Scan 很相似,都是基于索引的扫描,但是BitmapIndex Scan 节点每次执行返回的是一个位图而不是一个元组,其中位图中每位代表了一个扫描到的数据块。而BitmapHeap Scan一般会作为BitmapIndex Scan 的父节点,将BitmapIndex Scan 返回的位图转换为对应的元组。这样做最大的好处就是把Index Scan 的随机读转换成了按照数据块的物理顺序读取,在数据量比较大的时候,这会大大提升扫描的性能。

2. 大多数情况下, Index Only Scan < Index Scan < Bitmap Scan < Seq Scan

  • Index Scan 要比 Seq Scan 快。但是如果获取的结果集占所有数据的比重很大时,这时Index Scan 因为要先扫描索引再读表数据反而不如直接全表扫描来的快。
  • 如果获取的结果集的占比比较小,但是元组数很多时,可能Bitmap Index Scan 的性能要比Index Scan 好。
  • 如果获取的结果集能够被索引覆盖,则Index Only Scan 因为不用去读数据,只扫描索引,性能一般最好。但是如果VM 文件未生成,可能性能就会比Index Scan 要差。

四、 其他

  • Seq Scan:全表扫描 无启动时间

  • Index Scan:索引扫描

  • Bitmap Index Scan 位图索引扫描

  • Bitmap Heap Scan:位图索引扫描

  • Subquery Scan 子查询 无启动时间

  • Tid Scan ctid = …条件 无启动时间

  • Function Scan 函数扫描 无启动时间

  • Nested Loop 循环结合 无启动时间

  • Merge Join 合并结合 有启动时间

  • Hash Join 哈希结合 有启动时间

  • Sort 排序,ORDER BY操作 有启动时间

  • Hash 哈希运算 有启动时间

  • Result 函数扫描,和具体的表无关 无启动时间

  • Unique DISTINCT,UNION操作 有启动时间

  • Limit LIMIT,OFFSET操作 有启动时间

  • Aggregate count, sum,avg, stddev集约函数 有启动时间

  • Group GROUP BY分组操作 有启动时间

  • Append UNION操作 无启动时间

  • Materialize 子查询 有启动时间

  • Filter:条件过滤

  • Nestloop Join:嵌套循环连接,是在两个表做连接时,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,因此整个查询返回的结果集不能太大,要把返回子集较小的表作为外表,而且在内表的连接字段上要有索引,否则会很慢。执行过程:

    1.确定一个驱动表(outer table),另一个表为 inner table
    2. 驱动表中的每一行与 inner 表中的相应记录 JOIN 类似一个嵌套的循环

  • Hash Join:使用两个表中较小的表,并利用连接键在内存中建立散列表,然后扫描较大的表并探测散列表,找出与散列表匹配的行。适用于较小的表可以完全放入内存中的情况。如果表很大,不能完全放入内存,优化器会将它分割成若干不同的分区,把不能放入内存的部分写入磁盘的临时段。

  • Merge Join:如果源数据上有索引,或者结果已经被排过序,在执行排序合并连接时就不需要排序了,Merge Join 的性能会优于散列连接。
    执行计划运算类型 操作说明 是否有启动时间

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

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

相关文章

[论文笔记]P-tuning

引言 今天带来第四篇大模型微调的论文笔记GPT Understands, Too。 本篇工作提出的方法是P-tuning,使用可训练的连续提示嵌入,使GPT在NLU上表现比传统的全量微调的GPT更好的效果。P-tuning还提高了BERT在少样本和监督设定下的性能,大幅减少了提示工程的需求。 总体介绍 根…

Django(21):使用Celery任务框架

目录 Celery介绍Celery安装Celery使用项目文件和配置启动Celery编写任务调用异步任务查看任务执行状态及结果 设置定时和周期性任务配置文件添加任务Django Admin添加周期性任务启动任务调度器beat Flower监控任务执行状态Celery高级用法与注意事项给任务设置最大重试次数不同任…

2023-09-28 mysql-代号m-schema调研-文档记录

摘要: mdb中的database与mdb中的database的概念南辕北辙, 可以说有着本质的不同. mysql中的database可以看作是table的namespace, 而在mdb中, 与此相似的概念也就是table的namespace的概念, 是schema. 为了将mysql的db与mdb的schema建立映射关系后的技术风险可控, 需要详细分…

26663-2011 大型液压安全联轴器 课堂随笔

声明 本文是学习GB-T 26663-2011 大型液压安全联轴器. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了大型液压安全联轴器的分类、技术要求、试验方法及检验规则等。 本标准适用于联接两同轴线的传动轴系&#xff0c;可起到限制…

面试算法14:字符串中的变位词

题目 输入字符串s1和s2&#xff0c;如何判断字符串s2中是否包含字符串s1的某个变位词&#xff1f;如果字符串s2中包含字符串s1的某个变位词&#xff0c;则字符串s1至少有一个变位词是字符串s2的子字符串。假设两个字符串中只包含英文小写字母。例如&#xff0c;字符串s1为&quo…

软考高级之系统架构师之软件需求工程

概述 一个完整的软件生存周期是以需求为出发点。软件需求是指用户对系统在功能、行为、性能、设计约束等方面的期望。 需求开发&#xff1a; 需求获取需求分析需求定义&#xff08;需求规格说明书&#xff09;需求验证 需求管理: 变更控制版本控制需求跟踪需求状态跟踪 需…

零基础Python经验体验代码检查工具

作者&#xff1a;yd_257945187 原文链接&#xff1a;零基础Python经验体验代码检查工具-云社区-华为云 1 开发小白自述 年初&#xff0c;我开始从java语言转战Python语言的开发&#xff0c;对于零基础python经验的人来说&#xff0c;要开发出高质量且安全性能高的Python 代码…

解决craco启动react项目卡死在Starting the development server的问题

现象&#xff1a; 原因&#xff1a;craco.config.ts配置文件有问题 经过排查发现Dev开发模式下不能有splitChunk的配置&#xff0c; 解决办法&#xff1a; 加一个生产模式的判断&#xff0c;开发模式不加载splitChunk的配置&#xff0c;仅在生产模式才加载 判断条件代码&#…

notepad++配置python2环境

&#xff08;1&#xff09;python2版本下载&#xff1a;Index of /ftp/python/2.7.8/https://www.python.org/ftp/python/2.7.8/ &#xff08;2&#xff09; 配置notepad环境 1.打开Notepad&#xff0c;点击“插件”-“插件管理器”&#xff0c;在“可用”选项卡中&#xff0c…

云安全之访问控制介绍

访问控制技术背景 信息系统自身的复杂性、网络的广泛可接入性等因素&#xff0c;系统面临日益增多的安全威胁&#xff0c;安全问题日益突出&#xff0c;其中一个重要的问题是如何有效地保护系统的资源不被窃取和破坏。 访问控制技术内容包括访问控制策略、访问控制模型、访问…

《学术小白学习之路13》基于DTM和主题共现网络——实现主题时序演化网络分析(数据代码在结尾)

《学术小白学习之路13》基于DTM和主题共现网络实现主题演化网络分析 一、数据导入二、数据预处理2.1分词2.2 向量化三、DTM建模3.1 主题一致性检验3.2主题建模四、计算主题的相似度4.1获取文档主题分布4.2 时期分组4.3相似度计算4.3.1第一时期和第二时期的对比4.3.2第二时期与第…

ip地址可以精确定位吗

在互联网时代&#xff0c;IP地址的重要性不言而喻。作为网络通信的基础&#xff0c;IP地址用于标识每一台连接到互联网的设备。然而&#xff0c;传统的IP地址定位方式仅能粗略地确定设备的大致位置&#xff0c;无法实现精确定位。那么&#xff0c;IP地址能否实现精确定位呢&…

浅谈ChatGPT附免费体验地址

首先&#xff0c;让我来介绍一下ChatGPT是什么。ChatGPT是由OpenAI开发的大型语言模型&#xff0c;它代表着自然语言处理领域的最新进展。这个模型是通过大量的数据和先进的深度学习技术训练而成&#xff0c;具备了强大的语言理解和生成能力。 那么&#xff0c;ChatGPT能做些什…

我开源了一个加密算法仓库,支持18种算法!登录注册业务可用!

文章目录 仓库地址介绍安装用法SHA512HMACBcryptScryptAESRSAECC 仓库地址 仓库地址&#xff1a;https://github.com/palp1tate/go-crypto-guard 欢迎star和fork&#xff01; 介绍 此存储库包含用 Go 编写的全面的密码哈希库。该库支持多种哈希算法&#xff0c;它允许可定制…

在使用v-for时,为什么要加key

在Vue中&#xff0c;v-for 是一个强大的指令&#xff0c;用于循环渲染列表数据。然而&#xff0c;当你使用 v-for 渲染列表时&#xff0c;经常会遇到一个重要的问题&#xff1a;为什么一定要为每个循环项指定一个 key 属性&#xff1f;这篇博文将深入探讨这个问题&#xff0c;从…

前端监控日志产品

前言 流量分析的监控有&#xff1a;百度统计、谷歌分析、GrowingIo、友盟 错误统计的监控有&#xff1a;sentry、fundebug、frontJs、岳鹰 前端监控产品&#xff1a;OneApm、听云 开源的&#xff1a;logan web、Matomo PS&#xff1a;加粗的是博主用过的&#xff0c;sentr…

国庆周《Linux学习第二课》

Linux开篇指南针环境安装(第一课)-CSDN博客 Linux详细的环境安装介绍在上面 第一 环境准备过程 安装过程

Python绘图系统22:实现系统菜单

文章目录 文件菜单子部件开关 Python绘图系统&#xff1a; 前置源码&#xff1a; Python打造动态绘图系统&#x1f4c8;一 三维绘图系统 &#x1f4c8;二 多图绘制系统&#x1f4c8;三 坐 标 轴 定 制&#x1f4c8;四 定制绘图风格 &#x1f4c8;五 数据生成导入&#x1f4c8;…

消息认证的算法 Message Authentication Code 介绍

消息认证码&#xff08;Message Authentication Code&#xff0c;MAC&#xff09;是一种用于验证消息完整性和真实性的密码学算法。MAC通常与密钥一起使用&#xff0c;以确保接收方可以验证消息未被篡改或伪造。以下是MAC的一些重要特点和常见算法&#xff1a; 特点&#xff1…

React antd Table点击下一页后selectedRows丢失之前页选择内容的问题

一、问题 使用了React antd 的<Table>标签&#xff0c;是这样记录选中的行id与行内容的&#xff1a; <TabledataSource{data.list}rowSelection{{selectedRowKeys: selectedIdsInSearchTab,onChange: this.onSelectChange,}} // 表格是否可复选&#xff0c;加 type: …