如何为 openGauss 调优带有“IN 子查询”的 SQL ?

openGauss 是一种开源的关系型数据库管理系统(RDBMS),它起源于 PostgreSQL。openGauss 旨在提供高性能、高可用性和企业级功能。最初由华为开发,后来被开源给社区。openGauss 的 SQL 优化器基于 PostgreSQL,但经过了显著的增强和修改,以提升性能、可扩展性并支持企业级工作负载。虽然官方文档中没有明确说明 openGauss 是从哪个 PostgreSQL 版本继承的初始代码库,但普遍认为 openGauss 起源于 PostgreSQL 9.2.4。因此,当前版本的 openGauss 中可能仍然存在一些来自旧版 PostgreSQL 的遗留 SQL 优化器问题。

在不成熟的 SQL 优化器中,一个常见问题是对 IN 子查询的低效处理。以下是一个带有 IN 子查询的 SQL 语句示例。该查询从 employee 表中检索与 emp_subsidiary 表中 salary 匹配的记录,条件是两者的 emp_id 相同。

select *
  from employee a
 where a.emp_salary in (select b.emp_salary
                          from emp_subsidiary b
                         where a.emp_id = b.emp_id)

以下是查询计划;完成该查询需要 7.2 秒。

查询计划显示了对 employee 表的顺序扫描(sequence scan)和对 emp_subsidiary 表的索引扫描(index scan)。然而,这种查询不适合 employee 与 emp_subsidiary 比例为 30:1 的场景。如果 openGauss 拥有更强大的 SQL 优化器,它应该包含一个内部的 SQL 语法重写机制,将 IN 语句转换为 JOIN 或 EXISTS 语句,从而允许探索更高效的查询计划。>br>

下面,我将使用 EXISTS 语句重写 SQL,如下所示:

select *
  from employee a
 where exists (select ‘x’
                 from emp_subsidiary b
                where a.emp_salary = b.emp_salary and
                      a.emp_id = b.emp_id)


重写后的 SQL 仅需 0.34 秒 即可完成,并且在查询计划中使用了 Merge Semi Join——这是一种无法通过原始 IN 语法生成的计划。我们可以看到,重写后的 SQL 成本显著低于原始 SQL 语句。这表明,在 openGauss 对原始查询进行 SQL 优化时,Merge Semi Join 计划并未在其探索的计划空间内。

重写后的 SQL 比原始 SQL 快 20 倍以上。这种优化也可以通过使用 Tosska SQL Tuning Expert 在 openGauss 中实现。

Tosska SQL Tuning Expert Pro (TSEG Pro™) for openGauss® – 珠海图思科软件有限公司

Tosska SQL Tuning Expert Pro (TSEG Pro™) for openGauss® – 系统需求

在安装 Tosska SQL Tuning Expert Pro (TSEG Pro™) for openGauss® 之前, 请确保您的系统满足以下最低硬件和软件要求:

CPU 1.8 GHz 处理器
内存 最小2 GB内存,建议4 GB内存
硬盘空间 用于安装的200 MB硬盘空间
操作系统 Microsoft Windows 7
Microsoft Windows 10
Microsoft Windows 11
.NET Framework Microsoft .NET Framework 4.5.2
数据库服务器 openGauss 数据库 5.0或更高版本

如何使用查询重写插件在 MySQL 数据库中调整 SQL II?

MySQL 中的查询重写插件是一个组件,允许您在执行之前修改传入的 SQL 查询。它提供了根据特定需求转换、路由、过滤或扩展查询的功能。

如果您已安装了该插件,可以使用以下 SQL 语句来定义您的 SQL 替换规则和错误消息处理.

INSERT INTO query_rewrite.rewrite_rules (message, pattern, replacement)
VALUES(Unique_ID, Original_SQL, Rewrite_SQL);

MySQL 中的 query_rewrite.rewrite_rules 表存储了 Query Rewriter 插件用于重写 SQL 查询的规则。该表包含两列:

Pattern – 此列代表触发 SQL 查询重写的模式或条件。它定义了要匹配的特定查询或查询模式。

Replacement – 此列指定应该应用于匹配的查询或查询模式的替换或转换。

当执行 SQL 查询时,Query Rewriter 插件会检查 query_rewrite.rewrite_rules 表以查找匹配的模式。如果模式与执行的查询匹配,插件将使用相应的替换重写查询。这使您能够根据特定的模式或条件修改查询结构、优化查询或添加自定义逻辑。
以下是一个包含硬编码字面量的 SQL 语句示例,执行该 SQL 需要 2.1 秒,并附有以下查询计划。

SELECT   *
FROM     employee
WHERE    emp_id in (SELECT emp_id id
                    FROM   emp_subsidiary
                    where  emp_dept < ‘D’)
ORDER BY emp_id LIMIT 1;

以下屏幕显示了通过 Tosska DB Ace SQL 调优工具识别出的性能显著提升的替代 SQL 语句。由于注入 JOIN ORDER 提示,此优化后的 SQL 查询比原始 SQL 快了300多倍.

现在,我们需要将这个优化后的 SQL 与原始 SQL 一起部署到数据库中。然而,一个挑战出现在条件“emp_dept < 'D'”上,当使用一个带有不同硬编码字面量的 SQL 语句,比如“emp_dept < 'E'”时,它与 SQL 文本不匹配。因此,我们必须使用数值占位符Placeholder来替换硬编码字面量,将其替换为占位符“?”,如下所示。

INSERT INTO query_rewrite.rewrite_rules (message, pattern, replacement)
VALUES(Unique_ID, Original_SQL, Rewrite_SQL);

Original_SQL

SELECT   *
FROM     employee
WHERE    emp_id in (SELECT emp_id id
                    FROM   emp_subsidiary
                    where  emp_dept < ?)
ORDER BY emp_id LIMIT 1

Rewrite_SQL

select   /*+ QB_NAME(QB1) JOIN_ORDER(`employee`@QB1, `emp_subsidiary`@QB2) */ *
from     employee
where    emp_id in (select /*+ QB_NAME(QB2) */ emp_id id
                    from   emp_subsidiary
                    where  emp_dept < ?)
order by emp_id limit 1

Tosska DB Ace for MySQL通过自动化发现优化SQL替代方案和部署具有数值占位符替换的SQL,简化了这一过程。

查询重写插件功能强大且易于使用。最具挑战性的方面是为性能较差的SQL语句找到替代SQL。Tosska DB Ace Enterprise for MySQL可以帮助您自动化这一过程,从识别性能较差的SQL语句到重写SQL语法并部署替代规则。

Tosska DB Ace Enterprise for MySQL – Tosska Technologies Limited

DBAM Tune Rewriter demo – YouTube

如何使用MySQL数据库中的Query Rewriter插件来调优SQL?

MySQL中的Query Rewriter插件是一个组件,允许您在执行SQL之前修改传入的SQL查询。它提供了根据特定需求转换、路由、过滤或扩展查询的能力。该插件在SQL层操作,并可用于优化查询性能、强制执行安全策略、实施数据分区策略或向查询添加附加业务逻辑。通过Query Rewriter插件,您可以自定义和塑造SQL查询,以满足特定需求,在MySQL服务器内灵活控制查询执行。

Query Rewriter查询转换功能使您能够将原始查询重写或转换为等效或更高效的形式。这对于优化性能、简化复杂查询或强制使用特定查询计划非常有用。

在使用此功能之前,您必须安装Query Rewriter插件。Query Rewriter的概念很简单,它是一组预定义的SQL语句,用于替换从应用程序程序触发的特定SQL语句模式。

如果您已安装了该插件,以下SQL语句可用于定义您的SQL替换规则和错误消息处理。

INSERT INTO query_rewrite.rewrite_rules (message, pattern, replacement)
VALUES(Unique_ID, Original_SQL, Rewrite_SQL);

在MySQL中,query_rewrite.rewrite_rules表存储了Query Rewriter插件用于重写SQL查询的规则。该表具有两列:
Pattern – 此列表示触发SQL查询重写的模式或条件。它定义了要匹配的特定查询或查询模式。

Replacement – 此列指定应应用于匹配的查询或查询模式的替换或转换。

当执行SQL查询时,Query Rewriter插件会检查query_rewrite.rewrite_rules表以查找匹配的模式。如果某个模式与执行的查询匹配,插件将使用相应的替换来重写查询。这使您能够根据特定的模式或条件修改查询结构、优化查询或添加自定义逻辑。
我利用message列来定义SQL替换规则的临时唯一标识,这样可以使用以下SQL提取实际的规则ID。

SELECT id into :SID FROM query_rewrite.rewrite_rules where message= Unique_ID;

当您对query_rewrite.rewrite_rules表中的查询重写规则进行更改时,这些更改不会立即生效。相反,MySQL会将规则缓存在内存中以提高性能。然而,如果您希望确保更新后的规则立即生效,可以调用query_rewrite.flush_rewrite_rules()函数。

CALL query_rewrite.flush_rewrite_rules();

如果发生加载错误,插件还会将Rewriter_reload_error状态变量设置为ON,并将错误消息存储在Message列中。

SELECT message FROM query_rewrite.rewrite_rules where id=:SID;

实际上,Query Rewriter插件功能强大且易于使用。最具挑战性的方面是为性能不佳的SQL语句找到替代的SQL语句。Tosska DB Ace Enterprise for MySQL可以帮助您自动化这个过程,从识别性能不佳的SQL语句到重写SQL语法和部署替代规则。

Tosska DB Ace Enterprise for MySQL – Tosska Technologies Limited

DBAM Tune Rewriter demo – YouTube

Tosska DB Ace Enterprise (DBAM™) for MySQL® – 系统需求

在安装 Tosska DB Ace Enterprise (DBAM™) for MySQL® 之前, 请确保您的系统满足以下最低硬件和软件要求:

CPU 1.8 GHz 处理器
内存 最小2 GB内存,建议4 GB内存
硬盘空间 用于64位安装的400 MB硬盘空间
操作系统 Microsoft Windows 7 64位
Microsoft Windows 10 64位
.NET Framework Microsoft .NET Framework 4.5.2
数据库服务器 MySQL 数据库 5.6或更高版本

如何使用计划指南(Plan Guide)为SQL Server中的数据库对象进行SQL优化 ?

利用SQL Server中的计划指南(Plan Guides)可以优化存储过程和触发器等数据库对象中特定查询的性能,从而提高查询效率,而无需修改应用程序的源代码。

以下是在不更改源代码的情况下,使用计划指南来优化SQL Server中第三方应用程序的SQL的步骤:

  1. 鉴定导致数据库对象性能问题的SQL语句。
  2. 创建一个计划指南,通过引入查询提示(query hints)来为指定的查询提供优化的执行计划,以影响优化器的决策过程。
  3. 测试计划指南,确保其提供了期望的性能改进,并且不会引起任何意外的副作用。
  4. 将计划指南部署到生产环境,并监控应用程序的性能,以确保计划指南正在使用,并提供了期望的性能改进。

在优化执行中不修改源代码的应用程序中的数据库对象的SQL语句之前,关键是要了解SQL语句与计划指南中指定的语句的匹配情况,包括空格和注释。此外,还要确保匹配执行SQL语句的数据库对象。
以下是一个示例,演示如何优化名为getRD2的数据库对象中的SQL语句。用户选择并突出显示了SQL语句。

创建计划指南可能一开始看起来很复杂,但它是一种宝贵的方法,可以提高SQL性能,而无需修改源代码或缺乏必要的权限。最耗时的部分是使用sp_create_plan_guide系统存储过程中的@hints = N’OPTION(query_hint [ ,…n ])’参数来找到SQL语句的最佳查询提示。如果您对SQL调优技术了解不深或没有足够的时间进行试验,可以使用一种简化该过程的解决方案。它可以捕获SQL语句,识别SQL源类型,自动优化查询提示,并便于计划指南的轻松部署。
以下产品自动识别了一个计划指南,如附带的截图所示,可以将SQL性能提升75.81%。

在确定了最佳的计划指南之后,我们可以将其与存储过程一起部署到SQL Server数据库中。这个部署将会改善名为getRD2的存储过程的性能,而无需对存储过程的源代码进行任何修改。

一旦您获得了适合SQL语句的合适提示解决方案,您还可以选择使用系统存储过程sp_create_plan_guide手动创建计划指南。

如需详细信息,请访问我们的网站并观看我们的演示视频。
Tosska DB Ace Enterprise for SQL Server – Tosska Technologies Limited
DBAS Tune SQL PG Object – YouTube