达梦 SQL 调优

本文介绍了SQL调优的重要性,强调了关注数据库配置、设计合理性以及定位高负载SQL的重要性。调优目标包括优化执行计划,减少IO和CPU成本。文中列举了表扫描、连接操作顺序和分组操作的优化策略,并提供了确定高负载SQL的方法。自动SQL调整工具和开发有效SQL语句的原则也被提及,如避免全索引扫描、困难的正则表达式,以及合理使用COUNT()等。此外,文章还讨论了UNION与UNIONALL、GROUP BY...HAVING的优化以及使用EXPLAIN和HINTs来改进执行计划。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介
SQL 调优作为数据库性能调优中的最后一个环节,对查询性能产生着直接的影响。在进行正式的 SQL 调优前,用户首先要关注下列几点:
1.达梦数据库安装时的配置参数是否符合应用场景需求;
2.达梦数据库的 INI 配置文件中各项参数是否已经处于最优配置;
3.应用系统中数据库设计是否合理。

现在介绍定位高负载的 SQL 语句的方法,利用自动 SQL 调整功能进行优化,以及如何开发有效的 SQL 语句和使用优化器提示来影响执行计划。

调优目标
SQL 调优的整体目标是使用最优的执行计划,这意味着 IO 以及 CPU 代价最小。具体而言调优主要关注下列方面:
 表扫描
如果计划中对某大表使用了全索引扫描,那么用户需要关注是否存在着该表的某个查询条件使得过滤后可以淘汰至少一半的数据量。通过添加相应的索引,全索引扫描可能被转换为范围扫描或等值查找。添加的二级索引可以包含该表上所有被选择项以避免 BLKUP2 操作
符的查找操作带来的第二次 IO 开销,但无疑这会增加二级索引的大小。用户需权衡二者的利弊以选择正确的处理方式。

 连接操作的顺序和类型
多表连接时,不同的连接顺序会影响中间结果集数量的大小,这时调优的目标就是要找到一种能使中间结果保持最小的连接顺序。
对于给定的一个连接或半连接,DM 可以用 HASH 连接、嵌套循环连接、索引连接或者是归并连接实现。通过分析表的数据量大小和索引信息,SQL 调优目标是选择最适宜的操作符。对半连接而言,HASH 连接还可细分为左半 HASH 和右半 HASH。用户可以通过始终对数
据量小的一侧建立 HASH 来进行调优。

 分组操作
分组操作往往要求缓存所有数据以找到属于同一组的所有数据,在大数据量情况下这会带来大量的 IO。用户应该检查 SQL 查询和表上索引信息,如果可以利用包含分组列的索引,那么执行计划就会使用排序分组从而不用缓存中间结果。

确定高负载的 SQL
在打开监控开关(ENABLE_MONITOR=1、MONITOR_TIME=1)后,可以通过查询动态视图

V$LONG_EXEC_SQLS

V$SYSTEM_LONG_EXEC_SQLS

来确定高负载的 SQL 语句。前者显示最近 1000 条执行时间较长的 SQL 语句,后者显示服务器启动以来执行时间最长的20 条 SQL 语句。例如:

SELECT * FROM V$LONG_EXEC_SQLS;

或者

SELECT * FROM V$SYSTEM_LONG_EXEC_SQLS;

23.4 自动 SQL 调整
使用查询优化向导工具,输入需要进行调整的 SQL 语句,向导工具将在分析完执行计划后给出推荐索引的提示。用户只需按提示建立相应索引即可。

23.5 开发有效的 SQL 语句
SQL 语言是一种相当灵活的结构化查询语言。用户可以利用多种不同形式的查询语句完成相同的查询功能。为了使执行效率达到最优,用户需要参考以下原则以开发出有效的 SQL语句:

1.避免使用 OR 子句
OR 子句在实际执行中会被转换为类似于 UNION 的查询。如果某一个 OR 子句不能利用上索引则会使用全表扫描造成效率低下,应避免使用。如果 OR 子句都是对同一列进行过滤,用户可以考虑使用 IN VALUE LIST 的过滤形式。
如:

SELECT … WHERE CITY = ‘SHANGHAI’ OR CITY = ‘WUHAN’ OR CITY =
‘BEIJING’;

调整为

SELECT … WHERE CITY IN( ‘SHANGHAI’,‘WUHAN’,‘BEIJING’);

2.避免使用困难的正则表达式
在 SQL 语言中,LIKE 关键字支配通配符匹配,含通配符的表达式被称为正则表达式。有的正则表达式可以自动优化为非匹配的。例如:a LIKE 'L%'可以优化为 a>=‘L’ AND a<‘M’,这样就可以用到 a 上的索引。即使没有索引,转换后的比较也更快。再如:a LIKE
'LM_‘可以转化为 a>=‘LM’ AND a<‘LN’ AND a LIKE ‘LM_’。虽然仍然包含着通配符匹配,但大大缩小了匹配的范围。所谓困难的正则表达式是指开头和结尾都为通配符的正则表达式,如’L%‘、’%L’,优化器没办法缩小它们的匹配范围,也不可能用到索引而必须使用全表扫描。因此要尽可能避免这样的正则表达式。如果仅仅是开头为通配符,用户可以在列 a 上建立 REVERSE(a)这样一个函数索引,利用函数索引反转待匹配项从而使用函数索引进行范围扫描。

3.灵活使用伪表(SYSDUAL)
首先可以利用伪表进行科学计算,执行语句 SELECT 3*4 FROM SYSDUAL,则可以得到结果 12;其次,在某些方面使用 SYSDUAL 可提高效率。例如:查询过程中要判断表 t1 中是否有满足 condition1 条件的记录存在,可执行以下语句:

SELECT COUNT(*) INTO x FROM t1 WHERE condition1;

然后根据变量 x 的取值来判断。但是当 t1 非常大时该语句执行速度很慢,而且由于不知道 SELECT 返回的个数,不能用 SELECT *代替。事实上这个查询可以利用伪表来完成:

SELECT ‘A’ INTO y FROM SYSDUAL WHERE EXISTS (SELECT 1 FROM t1 WHERE
condition1);

判断 y 值,如等于’A’则 T1 中有记录。调整后的语句执行速度明显比上一句高。另外,在 DM 的语法里是可以省略 FROM 子句的,这时系统会自动加上 FROM SYSDUAL。因此前面的科学计算例子可以简化为 SELECT 3*4;

4.SELECT 项避免„*‟
除非用户确实要选择表中所有列,否则 SELECT *这种写法将让执行器背上沉重的负荷。因为每一列的数据不得不自下往上层层向上传递。不仅仅如此,如果用户查询的是列存储表,那么列存储所带来的 IO 优势将损耗殆尽。任何时候,用户都要了解表结构和业务需求,小心地选择需要的列并一一给出名称,避免直接用 SELECT *。

5.避免功能相似的重复索引
索引并非越多越好。抛开优化器面对众多索引逐一试探所耗费的时间不谈,如果表上增删改操作频繁,那么索引的维护将会成为大麻烦,尤其是函数索引的计算开销更不能忽略。

6.使用 COUNT()统计结果行数
如果对单表查询 COUNT(
)且没有过滤条件,那么 DM 优化器会直接读取相关索引中存储的行数信息,加以回滚段中其他事务插入或删除元组的行数修正,迅速地给出最终结果而避免对实际数据的读取。相比之下,COUNT(列名)会对数据进行读操作,执行效率远低于
COUNT()。即使查询中含有过滤条件,由于 DM 特有的批处理方式,COUNT()依旧快于其他写法。这是因为 COUNT()无需取得行的具体值而仅仅需要行数这一信息。需要额外说明的是,COUNT()会将 NULL 值计算在内而 COUNT(列名)是不包含 NULL
值的,因此用户要结合应用场景决定是否可以使用 COUNT(*)。

7.使用 EXPLAIN 来查看执行计划
在查询语句或者插入、删除、更新语句前增加 EXPLAIN 关键字,DM 将显示其执行计划而无需实际执行它。查阅

V$SQL_NODE_NAME

表中每个操作符的含义,用户可以很方便且
直观地了解数据如何被处理及传递。如果启用了统计信息收集,那么对照执行计划和对动态视图

V$SQL_NODE_HISTORY

V$SQL_NODE_NAME

的查询结果,用户就可以知道在实际执
行中每一个操作符执行的时间,进而找出性能瓶颈。

8.UNION 和 UNION ALL 的选择
UNION 和 UNION ALL 的区别是前者会过滤掉值完全相同的元组,为此 UNION 操作符需要建立 HASH 表缓存所有数据并去除重复,当 HASH 表大小超过了 INI 参数指定的限制时还会做刷盘。因此如果应用场景并不关心重复元组或者不可能出现重复,那么 UNION ALL 无疑优于UNION。

9.优化 GROUP BY … HAVING
GROUP BY 最常见的实现有 HASH 分组(HAGR)和排序分组(SAGR)。前者需要缓存中间结果;如果用户在 GROUP BY 的列上建立索引,那么优化器就会判断并可能使用上该索引,这时的 GROUP BY 就会变为 SAGR。HAVING 是分组后对结果集进行的过滤,如果过滤条件无关集函数操作,用户可以考虑将过滤条件放在 WHERE 而不是 HAVING 中。DM 优化器会判断并自动转换部分等效于 WHERE的 HAVING 子句,但显式地给出最佳 SQL 语句会让优化器工作得更好。

10.使用优化器提示(HINT)
利用经验对优化器的计划选择进行调整,HINT 是 SQL 调整不可或缺的一步。

更多资讯请上达梦技术社区了解:https://eco.dameng.com

### 达梦数据库性能的方法与最佳实践 达梦数据库(DM Database)作为国产数据库的代表之一,其性能方法和最佳实践对于确保系统高效运行至关重要。以下是针对达梦数据库性能的关键点及其对应的优化策略: #### 1. 连接池优化 连接池是数据库性能的重要环节之一。在达梦数据库中,使用 Druid 连接池时需特别注意以下几点: - 验证查询语句应避免使用 `SELECT 1`,而改用 `SELECT 1 FROM DUAL`[^3]。 - 长时间空闲的连接可能导致失效,因此需要设置合理的连接检测策略。 - 连接的最大存活时间 (`maxLiveTime`) 建议不超过 4 小时,以防止因长时间未使用而导致的连接问题。 #### 2. SQL 查询优化 SQL 查询的效率直接影响数据库的整体性能。优化 SQL 查询可以从以下几个方面入手: - **索引优化**:为频繁查询的字段创建合适的索引,但需注意避免过多索引导致写操作变慢。 - **避免全表扫描**:通过分析执行计划,确保查询能够有效利用索引。 - **减少不必要的子查询**:尽量将复杂的子查询转换为 JOIN 操作,以提高查询效率。 #### 3. 系统参数 达梦数据库提供了丰富的系统参数供用户整,以适应不同的业务场景。以下是一些关键参数的优化建议: - **缓冲区大小**:根据服务器内存情况,合理设置数据缓冲区大小 (`DATA_BUFFER`) 和日志缓冲区大小 (`LOG_BUFFER`)。 - **并行度**:对于大规模数据处理任务,可以适当提高并行度参数 (`PARALLEL_DEGREE`),以充分利用多核 CPU 的计算能力。 - **锁超时时间**:整锁等待超时时间 (`LOCK_TIMEOUT`),避免因长时间等待锁而导致的性能瓶颈。 #### 4. 监控与故障排查 有效的监控是性能的重要手段。针对达梦数据库的监控难点,可采取以下措施: - 使用专门的监控工具(如乐维监控),确保对数据库状态进行全面、实时的监控[^2]。 - 定期分析慢查询日志,定位性能瓶颈。 - 关注关键指标(如 CPU 使用率、内存使用率、I/O 等),及时发现潜在问题。 #### 5. 用户案例与实战经验 参考成功用户的实践经验也是性能的重要途径。通过查阅达梦官网或社区发布的用户成功案例,可以了解不同行业、不同规模的企业如何解决实际问题,并从中汲取适用的解决方案和最佳实践[^1]。 ```python # 示例:达梦数据库的系统参数 ALTER SYSTEM SET DATA_BUFFER = '8G'; ALTER SYSTEM SET LOG_BUFFER = '512M'; ALTER SYSTEM SET PARALLEL_DEGREE = 4; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值