达梦数据库查询较慢的快速诊断及优化

 更新时间:2025年10月29日 08:32:50   作者:百代繁华一朝都-绮罗生  
在达梦数据库中,慢SQL查询不仅会影响系统的性能,还会降低用户体验,这篇文章主要介绍了达梦数据库查询较慢的快速诊断及优化的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

1 快速诊断:定位瓶颈所在

1.1 查看当前慢SQL

– 最慢的 20 条 SQL 统计

SELECT TOP 20 START_TIME,TIME_USED/1000 TIME_USED,TOP_SQL_TEXT FROM V$SQL_HISTORY ORDER BY TIME_USED DESC;
SELECT * FROM V$SYSTEM_LONG_EXEC_SQLS ORDER BY EXEC_TIME DESC;

–查询慢 SQL 及阻塞

SELECT
        DS.SESS_ID "被阻塞的会话ID",
        DS.SQL_TEXT "被阻塞的SQL",
        DS.TRX_ID "被阻塞的事务ID",
        (CASE L.LTYPE WHEN 'OBJECT' THEN '对象锁' WHEN 'TID' THEN '事务锁' END CASE ) "被阻塞的锁类型",
        DS.CREATE_TIME "开始阻塞时间",
        SS.SESS_ID "占用锁的会话ID",
        SS.SQL_TEXT "占用锁的SQL",
        SS.CLNT_IP "占用锁的IP",
        L.TID "占用锁的事务ID"
FROM
        V$LOCK L
LEFT JOIN V$SESSIONS DS
ON
        DS.TRX_ID = L.TRX_ID
LEFT JOIN V$SESSIONS SS
ON
        SS.TRX_ID = L.TID
WHERE
        L.BLOCKED = 1;

1.2 检查系统资源状态

– 查看缓存命中率

数据缓冲区是 DMSERVER 在将数据页写入磁盘之前以及从磁盘上读取数据页之后,数据页所存储的地方。

数据缓冲区设定得太小,会导致缓冲页命中率低,磁盘 IO 频繁;将其设定得太大,又会导致操作系统内存本身不够用。

select
      name 缓冲池名称,
      sum(page_size)*sf_get_page_size 缓冲池大小_G,
      sum(rat_hit) /count(*) 命中率
from
      v$bufferpool
group by name;

2 SQL语句优化

2.1 分析执行计划

– 对慢SQL生成执行计划

EXPLAIN SELECT * FROM your_table WHERE your_conditions;

执行计划重点关注:

是否使用了合适的索引(INDEX SCAN)

避免全表扫描(CROSS INDEX SCAN)

注意排序操作(SORT)是否必要

2.2 常见SQL优化技巧

– 避免 SELECT *,只取需要的字段

SELECT id, name FROM users WHERE status = 1;  -- 好
SELECT * FROM users WHERE status = 1;         -- 差

– 为查询条件字段添加索引

CREATE INDEX idx_users_status ON users(status);

– 避免在WHERE条件中对字段进行函数操作

SELECT * FROM orders WHERE DATE_FORMAT(create_time, '%Y-%m') = '2024-01';  -- 差
SELECT * FROM orders WHERE create_time >= '2024-01-01' AND create_time < '2024-02-01';  -- 好

– 使用EXISTS代替IN(大数据量时)

SELECT * FROM table1 WHERE EXISTS (
    SELECT 1 FROM table2 WHERE table1.id = table2.id
);

3. 索引优化策略

3.1 检查缺失索引

– 查找可能需要索引的表

  • 频繁用于查询条件的列所在的表:如果某个表的列经常出现在 WHERE 子句中作为查询条件,该表可能需要索引。
  • 主键或唯一性约束的表:达梦数据库会自动为这些列创建索引,但如果需要额外的查询优化,可以手动添加其他索引。
  • 连接操作中使用的列所在的表:如果某个表经常在 JOIN 操作中使用,可以为连接列创建索引以提高性能。
  • 数据量较大的表:对于数据量较大的表,适当的索引可以显著减少查询时间。
  • 排序或分组操作中使用的列所在的表:如果某个表的列经常用于 ORDER BY 或 GROUP BY 操作,可以考虑创建索引。

3.2 创建合适的索引

在以下场景下可考虑创建索引:

仅当要通过索引访问表中很少的一部分行(1%~20%)。
索引可覆盖查询所需的所有列,不需额外去访问表。

存在下列情况将导致无法使用索引:

组合索引中,条件列中没有组合索引的首列。
条件列带有函数或计算。
索引排序是按照字段值进行排序的,字段值通过函数或计算后的值索引无法获取。
索引过滤性能不好时。

4. 数据库参数优化

4.1 关键性能参数检查

内存相关
BUFFER = 10000 # 缓冲区大小(MB),建议系统内存的50-70%
MAX_BUFFER = 10000 # 最大缓冲区
SORT_BUF_SIZE = 200 # 排序缓冲区(MB)
HJ_BUF_SIZE = 200 # HASH连接缓冲区(MB)

#并行处理
PARALLEL_POLICY = 1 # 启用并行
PARALLEL_THREAD_NUM = 4 # 并行线程数

#优化器相关
OPTIMIZER_MODE = 1 # 优化器模式

5. 统计信息维护

5.1 更新统计信息

– 更新表的统计信息

CALL SP_TAB_STAT_INIT('SCHEMA_NAME', 'TABLE_NAME');

– 更新整个模式的统计信息

CALL SP_DB_STAT_INIT('SCHEMA_NAME');

– 收集列统计信息

CALL SP_COL_STAT_INIT('SCHEMA_NAME', 'TABLE_NAME', 'COLUMN_NAME');

5.2 定期维护脚本

举例:

– 更新模式 DB_TEST 下的统计信息

DBMS_STATS.GATHER_SCHEMA_STATS('DB_TEST', 100, TRUE, 'FOR ALL COLUMNS SIZE AUTO');

– 更新特定表的统计信息

DBMS_STATS.GATHER_TABLE_STATS('username', 'table_name', null, 100, TRUE, 'FOR ALL COLUMNS SIZE AUTO', cascade => true, degree => 8);

– 更新所有表和索引的统计信息并记录日志

drop table if exists my_tab_stats;
create table my_tab_stats(table_name varchar2(100),owner varchar2(100),stat_flag varchar2(5),begin_time timestamp,end_time timestamp);
insert into my_tab_stats(table_name,owner) select table_name,owner from dba_tables where owner in ('OA');
update my_tab_stats set stat_flag = 0;
commit;
begin
    for tb in (select rowid,table_name,owner from my_tab_stats where stat_flag = 0 ) 
	loop
        update my_tab_stats set begin_time=sysdate where my_tab_stats.table_name=tb.table_name and my_tab_stats.owner=tb.owner;
        dbms_stats.gather_table_stats(tb.owner,tb.table_name,null,100,true,'FOR ALL COLUMNS SIZE AUTO',cascade => true, degree => 8);
        update my_tab_stats set stat_flag = 1,end_time=sysdate where my_tab_stats.table_name = tb.table_name and my_tab_stats.owner=tb.owner;
        commit;
    end loop;
end;

6. 架构和设计优化

6.1 分区表优化

– 对大表进行分区
CREATE TABLE sales (
sale_id INT,
sale_date DATE,
amount DECIMAL(10,2)
)
PARTITION BY RANGE(sale_date)
(
PARTITION p2023 VALUES LESS THAN (‘2024-01-01'),
PARTITION p2024 VALUES LESS THAN (‘2025-01-01')
);

6.2 物化视图

– 为复杂查询创建物化视图

CREATE MATERIALIZED VIEW mv_sales_summary
REFRESH COMPLETE ON DEMAND
AS 
SELECT customer_id, SUM(amount) as total_amount,
       COUNT(*) as order_count
FROM sales 
GROUP BY customer_id;

7. 紧急优化措施

如果系统正在经历严重性能问题:

—立即终止阻塞会话:

SP_CLOSE_SESSION(session_id); – 谨慎使用!
—清理缓存:
—重启数据库服务(最后手段)

优化实施建议

  • 从易到难:先优化SQL语句,再调整索引,最后修改参数
  • 测试环境验证:所有优化先在测试环境验证
  • 监控效果:优化后持续监控性能变化
  • 定期维护:建立定期的统计信息更新和索引重建任务

总结

到此这篇关于达梦数据库查询较慢的快速诊断及优化的文章就介绍到这了,更多相关达梦数据库查询较慢内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • DBeaver数据库转储、备份、迁移图文教程

    DBeaver数据库转储、备份、迁移图文教程

    DBeaver是一款强大的开源数据库管理工具,适用于多种数据库系统,包括但不限于MySQL、PostgreSQL、Oracle、SQL Server等,下面这篇文章主要给大家介绍了关于DBeaver数据库转储、备份、迁移的相关资料,需要的朋友可以参考下
    2024-07-07
  • 在ACCESS和SQL Server下Like 日期类型查询区别

    在ACCESS和SQL Server下Like 日期类型查询区别

    Like 和日期类型在ACCESS和SQL Server的区别,需要的朋友可以参考下。
    2009-10-10
  • DBeaver之如何导出数据库结构和数据

    DBeaver之如何导出数据库结构和数据

    这篇文章主要介绍了DBeaver之如何导出数据库结构和数据问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • 使用 Navicat 创建数据库并用JDBC连接的操作方法

    使用 Navicat 创建数据库并用JDBC连接的操作方法

    这篇文章主要介绍了使用 Navicat 创建数据库并用JDBC连接的操作方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • MySQL mysqldump命令使用详解

    MySQL mysqldump命令使用详解

    MySQL有很多可以导入数据的方法,然而这些只是数据传输中的一半,另外的一般是从MySQL数据库中导出数据。有许多的原因我们需要导出数据。一个重要的原因是用于备份数据库。数据的造价常常是昂贵的,需要谨慎处理它们。
    2006-12-12
  • 数据库中row_number() 分组排序函数的具体使用

    数据库中row_number() 分组排序函数的具体使用

    row_number()是一个强大的SQL窗口函数,它通过partitionby和orderby子句实现分组和排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-11-11
  • 三表左连接查询的sql语句写法

    三表左连接查询的sql语句写法

    left join三表左连接sql查询语句
    2008-09-09
  • DBeaver连接hive的超详细图解

    DBeaver连接hive的超详细图解

    dbeaver是一个图形化的界面工具,专门用于与各种数据库的集成,通过dbeaver我们可以与各种数据库进行集成通过图形化界面的方式来操作我们的数据库与数据库表,这篇文章主要给大家介绍了关于DBeaver连接hive的超详细图解,需要的朋友可以参考下
    2024-03-03
  • mybatis映射XML文件详解及实例

    mybatis映射XML文件详解及实例

    这篇文章主要介绍了mybatis映射XML文件详解及实例的相关资料,需要的朋友可以参考下
    2017-03-03
  • sql注入教程之类型以及提交注入

    sql注入教程之类型以及提交注入

    所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,这篇文章主要给大家介绍了关于sql注入教程之类型以及提交注入的相关资料,需要的朋友可以参考下
    2021-07-07

最新评论