SQL优化技术分享:从 321 秒到 0.2 秒的性能飞跃 —— 基于 PawSQL 的 TPCH 查询优化实战

在数据库性能优化领域,TPC-H 测试集是一个经典的基准测试工具,常用于评估数据库系统的查询性能。本文将基于 TPCH 测试集中的第 20个查询,结合 PawSQL 自动化优化工具,详细分析如何通过 SQL 重写和索引设计,将查询性能从 321 秒提升到 0.2 秒,性能提升高达1541倍。

1. 背景介绍:一个典型的多表关联分析查询

TPC-H作为业界公认的数据库性能测试基准,其第20号查询(Q20)是一个极具挑战性的复杂分析查询。这个查询的业务场景是:识别阿尔及利亚('ALGERIA')地区库存充足的供应商,具体条件是这些供应商提供的绿色('green%')零件的库存量(ps_availqty)超过该零件在过去一年内订单总量的一半。

原始SQL语句如下:

select s_name, s_address
from supplier, nation
where s_suppkey in (select ps_suppkeyfrom partsuppwhere ps_partkey in (select p_partkeyfrom partwhere p_name like 'green%')and ps_availqty > (select 0.5 * sum(l_quantity)from lineitemwhere l_partkey = ps_partkeyand l_suppkey = ps_suppkeyand l_shipdate >= date '1997-01-01'and l_shipdate < date '1997-01-01' + interval '1' YEAR)
)
and s_nationkey = n_nationkey 
and n_name = 'ALGERIA'
order by s_name

在实际测试环境中,这个查询的执行时间达到了惊人的321秒,完全无法满足业务系统的要求。

2. 性能瓶颈分析:为什么这么慢?

 

从执行计划可以看出主要性能问题:

  • 子查询执行次数多:相关子查询被执行了848次,每次耗时约378ms

  • 表扫描泛滥:对partsupp、part和lineitem表进行了全表扫描

  • 嵌套循环效率低:对lineitem表的访问在嵌套循环最内层

  • 排序操作代价高:最后需要对结果集进行排序

3. PawSQL的优化方案:系统性解决方案

PawSQL作为专业的SQL优化工具,针对上述问题提供了一套完整的优化方案:

3.1 SQL重写:从IN到EXISTS

将IN子查询转换为EXISTS形式,在有合适索引的情况下,这种改写通常能让优化器生成更高效的执行计划:

where exists (select /*QB_1*/ partsupp.ps_suppkeyfrom partsupp, (...)where exists (select /*QB_4*/ part.p_partkeyfrom partwhere part.p_name like 'green%' and part.p_partkey = partsupp.ps_partkey)and partsupp.ps_availqty > SQ_1742975670803.null_and partsupp.ps_suppkey = supplier.s_suppkeyand SQ_1742975670803.l_partkey = partsupp.ps_partkeyand SQ_1742975670803.l_suppkey = partsupp.ps_suppkey)

 

3.2 SQL重写:提前聚合计算

将lineitem的聚合计算从子查询中提取出来,预先计算每个(零件,供应商)组合的总量:

select 0.5 * sum(l_quantity) as null_, l_partkey,l_suppkey
from lineitem
where l_shipdate >= date '1997-01-01'and l_shipdate < date '1997-01-01' + interval '1' YEAR
group by l_partkey, l_suppkey

3.3 智能索引设计

除了SQL重写外,PawSQL还为优化后的SQL推荐了一系列索引,这些索引的创建为查询性能的提升提供了有力支持。

-- 加速lineitem表的聚合计算
CREATE INDEX PAWSQL_IDX1406058528 ON lineitem(l_shipdate,l_quantity,l_partkey,l_suppkey);-- 优化nation表查询
CREATE INDEX PAWSQL_IDX0006674720 ON nation(n_name,n_nationkey);-- 支持supplier表的排序和连接
CREATE INDEX PAWSQL_IDX1461825654 ON supplier(s_name,s_address,s_nationkey);
CREATE INDEX PAWSQL_IDX1670284145 ON supplier(s_nationkey,s_name,s_address);-- 加速part和partsupp表的连接
CREATE INDEX PAWSQL_IDX0450194419 ON part(p_partkey,p_name);
CREATE INDEX PAWSQL_IDX1262756509 ON partsupp(ps_partkey,ps_suppkey,ps_availqty);

3.4 谓词下推

将过滤条件尽可能下推到数据访问层,减少中间结果集:

  • nation.n_name = 'ALGERIA'

  • part.p_name like 'green%'

  • lineitem.l_shipdate范围条件

3.5. 避免排序

通过创建包含s_name的索引,直接利用索引的有序性避免排序操作。

4. 优化效果:性能提升1541倍

 

优化前后的对比令人震撼:

指标优化前优化后提升幅度
执行时间321秒0.208秒154,124%
lineitem表扫描次数848次1次-
lineitem表扫描行数509,285,056行90,514行-
排序操作需要显式排序利用索引避免排序-

执行计划对比

  • 优化前:全表扫描→嵌套循环→重复计算

  • 优化后:索引查找→哈希连接→物化视图

5. 经验总结:SQL优化最佳实践

通过这个案例,我们可以总结出以下SQL优化经验:

  1. 避免关联子查询:特别是重复执行的关联子查询,考虑改写为JOIN或提前物化

  2. 索引设计:尽量减少表扫描,同时兼顾避免回表操作

  3. 利用索引有序性:让索引顺序与ORDER BY一致可以避免排序操作

  4. 聚合计算预优化:对于重复的聚合计算,考虑提前计算并存储

  5. 专业工具辅助:使用PawSQL等专业工具可以快速定位问题并提供优化方案

这个案例生动展示了:即使是极其复杂的分析查询,通过系统性的优化方法,也能实现从分钟级到亚秒级的性能飞跃

🌐 关于PawSQL

PawSQL专注于数据库性能优化自动化和智能化,提供的解决方案覆盖SQL开发、测试、运维的整个流程,广泛支持包括MySQL/PostgreSQL/Oracle /openGauss/TDSQL/Oceanbase/达梦DM/金仓等各种主流商用和开源数据库,为开发者和企业提供一站式的创新SQL优化解决方案。

 

 

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

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

相关文章

SpringBoot3-web开发笔记(下)

内容协商 实现&#xff1a;一套系统适配多端数据返回 多端内容适配&#xff1a; 1. 默认规则 SpringBoot 多端内容适配。 基于请求头内容协商&#xff1a;&#xff08;默认开启&#xff09; 客户端向服务端发送请求&#xff0c;携带HTTP标准的Accept请求头。 Accept: applica…

Graylog 索引配置详解与优化建议

Graylog 索引配置详解与优化建议 &#x1f680; 前言一、索引集基础信息 &#x1f4da;二、分片&#xff08;Shards&#xff09;与副本&#xff08;Replicas&#xff09;设置 ⚙️1. 分片 (Shards)2. 副本 (Replicas) 三、 字段类型刷新间隔&#xff08;Field Type Refresh Int…

数据结构*包装类泛型

包装类 什么是包装类 在讲基本数据类型的时候&#xff0c;有提到过包装类。 基本数据类型包装类byteByteshortShortintIntegerlongLongfloatFloatdoubleDoublecharCharacterbooleanBoolean 我们知道&#xff1a;基本数据类型并不是对象&#xff0c;没有对象所具有的方法和属…

【JDBC-54.1】MySQL JDBC连接字符串常用参数详解

在Java应用程序中连接MySQL数据库时&#xff0c;JDBC连接字符串是建立连接的关键。一个配置得当的连接字符串不仅能确保连接成功&#xff0c;还能优化性能、增强安全性并处理各种连接场景。本文将深入探讨MySQL JDBC连接字符串的常用参数及其最佳实践。 1. 基本连接字符串格式…

[ctfshow web入门] web37

信息收集 题目有了变化&#xff0c;include$c if(isset($_GET[c])){$c $_GET[c];if(!preg_match("/flag/i", $c)){include($c);echo $flag;}}else{highlight_file(__FILE__); }解题 通过协议解题 参考[ctfshow web入门] web31 同样是include&#xff0c;之前的方…

Linux 调试代码工具:gdb

文章目录 一、debug vs release&#xff1a;两种程序形态的本质差异1. 什么是 debug 与 release&#xff1f;2. 核心差异对比 二、为什么需要 debug&#xff1a;从项目生命周期看调试价值1. 项目开发流程中的调试闭环&#xff08;流程图示意&#xff09;2. Debug 的核心意义与目…

Python设计模式:命令模式

1. 什么是命令模式&#xff1f; 命令模式是一种行为设计模式&#xff0c;它将请求封装为一个对象&#xff0c;从而使您能够使用不同的请求、队列或日志请求&#xff0c;以及支持可撤销操作。 命令模式的核心思想是将请求的发送者与请求的接收者解耦&#xff0c;使得两者之间的…

nlp面试重点

深度学习基本原理&#xff1a;梯度下降公式&#xff0c;将损失函数越来越小&#xff0c;最终预测值和实际值误差比较小。 交叉熵&#xff1a;-p(x)logq(x)&#xff0c;p(x)是one-hot形式。如果不使用softmax计算交叉熵&#xff0c;是不行的。损失函数可能会非常大&#xff0c;…

Leetcode:二叉树

94. 二叉树的中序遍历 class Solution {public List<Integer> inorderTraversal(TreeNode root) {TreeNode cur root;Stack<TreeNode> stack new Stack<>();List<Integer> list new ArrayList<>();while (!stack.isEmpty() || cur ! null) {…

SQL:Constraint(约束)

目录 &#x1f3af; 什么是 Constraint&#xff1f; MySQL 中常见的约束类型&#xff1a; 1. PRIMARY KEY 2. FOREIGN KEY 3. UNIQUE 4. NOT NULL 5. DEFAULT 6. CHECK&#xff08;MySQL 8.0&#xff09; 7. AUTO_INCREMENT &#x1f3af; 什么是 Constraint&#xf…

数据库数据恢复——sql server数据库被加密怎么恢复数据?

SQL server数据库数据故障&#xff1a; SQL server数据库被加密&#xff0c;无法使用。 数据库MDF、LDF、log日志文件名字被篡改。 数据库备份被加密&#xff0c;文件名字被篡改。 SQL server数据库数据恢复过程&#xff1a; 1、将所有数据库做完整只读备份。后续所有数据恢…

MySQL 用 limit 影响性能的优化方案

一.使用索引覆盖扫描 如果我们只需要查询部分字段&#xff0c;而不是所有字段&#xff0c;我们可以尝试使用索引覆盖扫描&#xff0c;也就是让查询所需的所有字段都在索引中&#xff0c;这样就不需要再访问数据页&#xff0c;减少了随机 I/O 操作。 例如&#xff0c;如果我们…

【算法笔记】并查集详解

&#x1f680; 并查集&#xff08;Union-Find&#xff09;详解&#xff1a;原理、实现与优化 并查集&#xff08;Union-Find&#xff09;是一种非常高效的数据结构&#xff0c;用于处理动态连通性问题&#xff0c;即判断若干个元素是否属于同一个集合&#xff0c;并支持集合合…

鸿蒙HarmonyOS埋点SDK,ClkLog适配鸿蒙埋点分析

ClkLog埋点分析系统&#xff0c;是一种全新的、开源的洞察方案&#xff0c;它能够帮助您捕捉每一个关键数据点&#xff0c;确保您的决策基于最准确的用户行为分析。技术人员可快速搭建私有的分析系统。 ClkLog鸿蒙埋点SDK通过手动埋点的方式实现HarmonyOS 原生应用的前端数据采…

JMeter的关联

关联&#xff1a;上一个请求的响应结果和下一个请求的数据有关系 xpath提取器 适用场景 HTML/XML文档结构化数据&#xff1a; 适用于从HTML或XML文档中提取结构化数据。例如&#xff0c;提取表格中的数据、列表中的项目等。示例&#xff1a;从HTML表格中提取所有行数据。 …

Spring Security 权限配置详解

&#x1f31f;Spring Security 权限配置详解&#xff1a;从基础到进阶 Spring Security 是一个功能强大、可高度自定义的安全框架&#xff0c;主要用于为基于 Spring 的应用程序提供身份验证和授权功能。 本篇文章将带你深入理解 Spring Security 的权限配置机制&#xff0c;掌…

pycharm中安装Charm-Crypto

一、安装依赖 1、安装gcc、make、perl sudo apt-get install gcc sudo apt-get install make sudo apt-get install perl #检查版本 gcc -v make -v perl -v 2、安装依赖库m4、flex、bison(如果前面安装过pypbc的话,应该已经装过这些包了) sudo apt-get update sudo apt…

【MCAL】AUTOSAR架构下基于SPI通信的驱动模块详解-以TJA1145为例

目录 前言 正文 1.TJA1145驱动代码中的SPI协议设计 1.1 对SPI Driver的依赖 1.2 对SPI配置的依赖 1.2.1 SpiExternalDevice 1.2.2 Channel_x 1.2.3 Job_x 1.2.4 Sequence N 1.2.5 Sequence M 1.2.6 Sequence L 1.2.7 小结 2.基于Vector驱动代码的SPI配置 2.1 SPI引…

JavaScript:BOM编程

今天我要介绍的是JS中有关于BOM编程的知识点内容&#xff1a;BOM编程&#xff1b; 介绍&#xff1a;BOM全名&#xff08;Browser Object Model&#xff08;浏览器对象模型&#xff09;&#xff09;。 是浏览器提供的与浏览器窗口交互的接口&#xff0c;其核心对象是 window。与…

Memcached缓存系统:从部署到实战应用指南

#作者&#xff1a;猎人 文章目录 一、安装libevent二、安装配置memcached三、安装Memcache的PHP扩展四、使用libmemcached的客户端工具五、Nginx整合memcached:六、php将会话保存至memcached Memcached是一款开源、高性能、分布式内存对象缓存系统&#xff0c;可应用各种需要缓…