当前位置: 首页 > news >正文

[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 的性能会优于散列连接。
    执行计划运算类型 操作说明 是否有启动时间

相关文章:

[ruby on rails] postgres sql explain 优化

一、查看执行计划 sql User.all.to_sql # 不会实际执行查询 puts ActiveRecord::Base.connection.explain(sql)# 会实际执行查询&#xff0c;再列出计划 User.all.explain# 会实际执行查询&#xff0c;再列出计划ActiveRecord::Base.connection.execute(EXPLAIN ANALYZE sql…...

YOLOv7改进:GAMAttention注意力机制

1.背景介绍 为了提高各种计算机视觉任务的性能&#xff0c;人们研究了各种注意机制。然而&#xff0c;以往的方法忽略了保留通道和空间方面的信息以增强跨维度交互的重要性。因此&#xff0c;我们提出了一种全局调度机制&#xff0c;通过减少信息缩减和放大全局交互表示来提高深…...

83、SpringBoot --- 下载和安装 MSYS2、 Redis

启动redis服务器&#xff1a; 打开小黑窗&#xff1a; C:\Users\JH>e: E:>cd E:\install\Redis6.0\Redis-x64-6.0.14\bin E:\install\Redis6.0\Redis-x64-6.0.14\bin>redis-server.exe redis.windows.conf 启动redis客户端&#xff1a; 小黑窗&#xff1a;redis-cli …...

用css画一个半圆弧(以小程序为例)

一、html结构 圆弧的html结构是 两个块级元素嵌套。 <View classNamewrap><View className"inner">{/* 图标下的内容 */}</View></View>二、css样式&#xff1a;原理是两个半圆叠在一起&#xff0c;就是一个半圆弧。那么&#xff0c;如何画一…...

redis介绍

一、简介 Redis 与其他 key - value 缓存产品有以下三个特点&#xff1a; Redis支持数据的持久化&#xff0c;可以将内存中的数据保存在磁盘中&#xff0c;重启的时候可以再次加载进行使用。 Redis不仅仅支持简单的key-value类型的数据&#xff0c;同时还提供list&#xff0c;…...

数学建模常用模型

作为数学建模的编程手还掌握一些各类模型常用算法&#xff0c;数学建模评价类模型、分类模型、预测类模型比较常用的方法总结如下&#xff1a; 接下来对这些比较典型的模型进行详细进行介绍说明。 一、评价模型 在数学建模中&#xff0c;评价模型是比较基础的模型之一&#x…...

Linux 基本语句_5_创建静态库|动态库

静态库 创建主函数&#xff1a;main.c 应用函数&#xff1a;add.c、sub.c、mul.c 创建calc.h文件作为头文件 生成可执行文件*.o文件 gcc -c add.c -o add.o ....包装*.o文件为静态库 ar -rc libmymath.a add.o sub.o mul.o编译静态库并指明创建静态库的位置 sudo gcc mai…...

【每日一题】2703. 返回传递的参数的长度

2703. 返回传递的参数的长度 - 力扣&#xff08;LeetCode&#xff09; 请你编写一个函数 argumentsLength&#xff0c;返回传递给该函数的参数数量。 示例 1&#xff1a; 输入&#xff1a;args [5] 输出&#xff1a;1 解释&#xff1a; argumentsLength(5); // 1只传递了一个值…...

虚拟DOM详解

面试题&#xff1a;请你阐述一下对vue虚拟dom的理解 什么是虚拟dom&#xff1f; 虚拟dom本质上就是一个普通的JS对象&#xff0c;用于描述视图的界面结构 在vue中&#xff0c;每个组件都有一个render函数&#xff0c;每个render函数都会返回一个虚拟dom树&#xff0c;这也就意味…...

Linux配置命令

一&#xff1a;HCSA-VM-Linux安装虚拟机后的基础命令 1.代码命令 1.查看本机IP地址&#xff1a; ip addr 或者 ip a [foxbogon ~]$ ip addre [foxbogon ~]$ ip a 1&#xff1a;<Loopback,U,LOWER-UP> 为环回2网卡 2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP&g…...

Kafka:介绍和内部工作原理

展示Kafka工作方式的简单架构。 什么是Kafka&#xff1f;为什么我们要使用它&#xff1f;它是消息队列吗&#xff1f; 它是一个分布式流处理平台或分布式提交日志。 Kafka通常用于实时流数据管道&#xff0c;即在系统之间传输数据&#xff0c;构建不断流动的数据转换系统和构…...

在 EMR Serverless 上使用 Delta Lake

本文是一份开箱即用的全自动测试脚本&#xff0c;用于在 EMR Serverless 上提交一个 Delta Lake 作业。本文完全遵循《最佳实践&#xff1a;如何优雅地提交一个 Amazon EMR Serverless 作业&#xff1f;》 一文给出的标准和规范&#xff01; 1. 导出环境相关变量 注意&#x…...

Stream流的使用详解(持续更新)

1. 对比两List集合数据某些字段一样的情况下取值&#xff1a; 一般简单方式我们会使用双重for循环来处理判断数据取值&#xff08;如下代码所示&#xff09;&#xff0c;但是数据量越大的情况下代码效率则越低&#xff0c;并且现在很多公司都会限制for循环层数所以更推荐strea…...

golang工程——gRpc 拦截器及原理

oauth2认证与拦截器 类似java spring中的拦截器。gRpc也有拦截器的说法&#xff0c;拦截器可作用于客户端请求&#xff0c;服务端请求。对请求进行拦截&#xff0c;进行业务上的一些封装校验等&#xff0c;类似一个中间件的作用 拦截器类型 一元请求拦截器流式请求拦截器链式…...

Python接口自动化之unittest单元测试

以下主要介绍unittest特性、运行流程及实际案例。 一、单元测试三连问 1、什么是单元测试&#xff1f; 按照阶段来分&#xff0c;一般就是单元测试&#xff0c;集成测试&#xff0c;系统测试&#xff0c;验收测试。单元测试是对单个模块、单个类或者单个函数进行测试。 将访…...

在亚马逊云科技Amazon SageMaker上部署构建聊天机器人的开源大语言模型

开源大型语言模型&#xff08;LLM&#xff09;已经变得流行起来&#xff0c;研究人员、开发人员和组织都可以使用这些模型来促进创新和实验。这促进了开源社区开展合作&#xff0c;从而为LLM的开发和改进做出贡献。开源LLM提供了模型架构、训练过程和训练数据的透明度&#xff…...

【51单片机】10-蜂鸣器

1.蜂鸣器的原理 这里的“源”不是指电源。而是指震荡源。 也就是说&#xff0c;有源蜂鸣器内部带震荡源&#xff0c;所以只要一通电就会叫。 而无源内部不带震荡源&#xff0c;所以如果用直流信号无法令其鸣叫。必须用2K~5K的方波去驱动它。 有源蜂鸣器往往比无源的贵&#xff…...

26377-2010 逆反射测量仪 知识梳理

声明 本文是学习GB-T 26377-2010 逆反射测量仪. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了逆反射测量仪的术语和定义、结构与分类、技术要求、计量学特性、试验方法、检验规 则以及标志、包装、运输与贮存。 本标准适用于…...

css实现渐变电量效果柱状图

我们通常的做法就是用echarts来实现 比如 echarts象形柱图实现电量效果柱状图 接着我们实现进阶版&#xff0c;增加渐变效果 echarts分割柱形图实现渐变电量效果柱状图 接着是又在渐变的基础上&#xff0c;增加了背景色块的填充 echarts实现渐变电量效果柱状图 其实思路是一…...

FileManager/本地文件增删改查, Cache/图像缓存处理 的操作

1. FileManager 本地文件管理器&#xff0c;增删改查文件 1.1 实现 // 本地文件管理器 class LocalFileManager{// 单例模式static let instance LocalFileManager()let folderName "MyApp_Images"init() {createFolderIfNeeded()}// 创建特定应用的文件夹func cr…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...