news 2026/8/6 1:06:14

达梦SQL从入门到实践:连接、DDL、DML与性能优化核心指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
达梦SQL从入门到实践:连接、DDL、DML与性能优化核心指南

1. 从“能用”到“会用”:为什么需要深入达梦SQL

如果你正在接触国产数据库,尤其是达梦数据库,那么“SQL”这个词对你来说一定不陌生。它就像是你和数据库之间沟通的“普通话”,无论是查询数据、更新记录,还是创建表结构,都离不开它。很多人觉得,SQL嘛,不就是SELECT * FROM table吗?我在MySQL、Oracle里都写过,换个数据库能有多大区别?直接上手不就行了。

我刚开始接触达梦时也是这么想的,结果很快就遇到了麻烦。一个在MySQL上跑得好好的分页查询,在达梦上性能却慢得离谱;一个简单的日期处理函数,语法报错让人摸不着头脑;更别提那些因为默认参数和兼容性设置不同而导致的“灵异”问题了。这让我意识到,把达梦SQL简单地等同于“标准SQL”或者“其他数据库的SQL”,是一个巨大的误区。达梦数据库在语法上高度兼容Oracle和SQL标准,这降低了入门门槛,但它的内核实现、优化器逻辑、特定函数以及大量为适应国产化环境而设计的特性,才是决定你能否高效、稳定使用的关键。

这篇内容,就是把我从“踩坑”到“填坑”过程中积累的那些最基础、也最容易出问题的达梦SQL知识梳理出来。它不是一份冰冷的命令手册,而是一份聚焦于“差异”和“实践”的生存指南。我们会避开那些在任何SQL教材里都能查到的通用语法,重点剖析那些达梦特有的细节、那些从其他数据库迁移过来时必然遇到的“坑”,以及如何写出在达梦上既正确又高效的SQL语句。无论你是刚刚接手一个达梦项目的新手,还是从其他数据库转战过来的老手,这些内容都能帮你快速建立起对达梦SQL的正确认知,少走弯路。

2. 连接与初探:你的第一个达梦SQL环境

在真正动手写SQL之前,一个稳定、可靠的连接环境是基础。达梦提供了官方管理工具DM管理工具,但对于习惯了NavicatDBeaver等第三方工具的开发者来说,如何连接往往是个问题。

2.1 核心连接参数解析

无论使用哪种工具,连接达梦数据库都需要几个核心参数。理解它们背后的含义,能帮你快速定位连接失败的问题。

  • 服务器地址与端口:最常见的地址是localhost127.0.0.1。端口默认为5236,这是达梦数据库服务实例监听端口。很多人在安装时会修改它,如果连接不上,首先检查端口是否正确。你可以通过查看达梦安装目录下dm.ini配置文件中的PORT_NUM参数来确认。
  • 服务名:在达梦中,更常用的连接标识是“服务名”,而不是像MySQL那样的“数据库名”。一个达梦数据库实例下可以创建多个“模式”(Schema),连接时指定的服务名通常对应一个具体的模式。对于初学者,服务名常常就是DMSERVER(默认实例名)或者你在安装时指定的名称。
  • 用户名与密码:默认的系统管理员账户是SYSDBA,其默认密码是SYSDBA这是一个极其重要的安全须知:在生产环境中,首次安装后必须立即修改SYSDBA的密码。此外,达梦支持SYSAUDITOR(审计管理员)和SYSSSO(安全管理员)等其他系统预定义用户。

注意:很多连接失败源于对“服务名”和“模式”的混淆。在达梦里,你连接的是“数据库实例+服务名”,登录后操作的对象存在于某个“模式”下。SYSDBA默认对应的模式是SYSDBA(与用户名相同)。创建新用户时,通常会关联一个同名的模式。

2.2 使用DBeaver连接达梦的实操细节

DBeaver因其开源和强大的多数据库支持,成为很多开发者的首选。用它连接达梦需要驱动。

  1. 下载达梦JDBC驱动:前往达梦官网,下载对应版本的DmJdbcDriverjar包(如DmJdbcDriver18.jar)。注意驱动版本与数据库服务器版本的大致匹配(如JDBC 18对应DM8)。
  2. 在DBeaver中新建连接:选择数据库类型时,如果没有“Dameng”或“DM”,可以选择“Oracle”(因为驱动兼容),或者更通用地,选择“Generic” -> “JDBC”。
  3. 关键配置
    • JDBC URL:这是核心。标准格式类似于:jdbc:dm://主机名:端口?schema=模式名&其它参数例如:jdbc:dm://localhost:5236?schema=SYSDBA
    • 驱动类名dm.jdbc.driver.DmDriver
    • 驱动文件:点击“添加文件”,将下载的DmJdbcDriver18.jar添加进来。
  4. 常见连接错误与解决
    • “网络通信异常”:检查数据库服务是否启动(systemctl status DmServiceDMSERVER或 Windows服务管理器),检查防火墙是否开放了5236端口。
    • “登录失败”:核对用户名、密码、服务名。注意密码大小写。
    • “驱动未找到”:确认驱动jar包路径正确,且DBeaver已正确加载。

2.3 模式(Schema)与用户(User)的关系

这是达梦(以及Oracle)与MySQL、SQL Server概念上的一大区别,务必厘清。 在MySQL中,你创建一个数据库(CREATE DATABASE),然后在这个库下创建表。用户被授予访问某个库的权限。 在达梦中,核心的概念是“模式”。一个用户通常对应一个同名的模式。当你用SYSDBA登录,你当前的操作模式默认就是SYSDBA模式。你创建的表(如果没有指定模式)都会放在SYSDBA模式下。

-- 创建一个新用户,并同时创建其同名模式 CREATE USER "TEST_USER" IDENTIFIED BY "Test12345678"; -- 授予该用户连接等基本权限 GRANT "PUBLIC", "RESOURCE" TO "TEST_USER"; -- 切换到TEST_USER用户连接后,以下语句创建的表位于 TEST_USER 模式下 CREATE TABLE my_table (id INT);

理解这一点至关重要,因为它影响着对象访问的SQL写法。当你要查询一个表时,可能需要指定模式名:SELECT * FROM SYSDBA.employee;或者SELECT * FROM TEST_USER.my_table;

3. 数据定义语言(DDL):建表时的“达梦特色”

创建表结构是项目开始的第一步。达梦的CREATE TABLE语法兼容SQL标准,但有一些自己的扩展和默认行为,需要特别注意。

3.1 字段数据类型的选择与坑

达梦支持丰富的数据类型,有些与Oracle高度相似,有些则有细微差别。

  • 字符类型

    • CHAR(n): 定长字符串,n最大为8188。如果数据长度不足,会用空格填充。适用于长度固定的代码、标志位。
    • VARCHAR(n): 变长字符串,n最大为8188。这是最常用的类型。注意,达梦的VARCHAR是以字符为单位计算长度,对于中文字符很友好。
    • VARCHAR2(n): 与VARCHAR几乎完全相同,提供它主要是为了兼容Oracle用户的习惯。在达梦中,你可以把它们视为同义词。

    实操心得:除非明确知道字段长度绝对固定且很短,否则一律使用VARCHAR(n)。避免使用CHAR存储变长数据,因为末尾空格可能会在比较和拼接时带来意想不到的问题,例如WHERE code = ‘A’可能查不到CHAR(10)类型字段值为‘A’(后面有9个空格)的记录。

  • 数值类型

    • NUMBER(p, s): 这是最通用、最精确的数值类型。p是精度(总位数),s是小数位数。例如NUMBER(10,2)表示总共10位,其中2位是小数。它可以存储整数、小数。
    • INT,INTEGER: 等同于NUMBER(38,0),用于存储大整数。
    • DECIMAL(p, s): 与NUMBER(p,s)功能相同。
    • DOUBLE,FLOAT: 用于浮点数运算,可能存在精度损失。

    建议:对于需要精确计算的金额、数量等字段,强烈推荐使用NUMBER(p,s)。明确指定精度和小数位,可以避免浮点数精度问题,也便于数据库优化。

  • 日期时间类型

    • DATE: 存储日期和时间,精确到秒。这是达梦默认的日期类型,也是最常用的。TIMESTAMP精度更高,但DATE在大多数业务场景下已足够。
    • TIMESTAMP: 时间戳,精度可以到微秒(取决于定义,如TIMESTAMP(6))。

    踩坑记录:很多从MySQL过来的人会习惯用DATETIME,达梦里没有这个类型,对应的就是DATE。另外,达梦的DATE类型是包含时分秒的,这与一些数据库(如Oracle,其DATE也含时分秒)一致,但与某些数据库的DATE(仅日期)不同。

3.2 建表示例与关键子句

CREATE TABLE “EMPLOYEE” ( “ID” NUMBER(10) PRIMARY KEY, -- 主键 “EMP_NAME” VARCHAR2(100) NOT NULL, -- 非空约束 “SALARY” NUMBER(12, 2) DEFAULT 0, -- 默认值 “HIRE_DATE” DATE DEFAULT SYSDATE, -- 默认当前系统日期 “DEPARTMENT_ID” NUMBER(6), “EMAIL” VARCHAR2(255), “RESUME” TEXT, -- 大文本字段 -- 创建表时指定存储表空间(非必须,但生产环境建议) STORAGE ( INITIAL 64, -- 初始区大小 64K NEXT 32, -- 下一个区大小 32K ON “MAIN” -- 表空间名 ) ) TABLESPACE “MAIN”; -- 指定表所属表空间

关键点解析:

  1. 双引号的使用:达梦默认对象名(表名、字段名)是不区分大小写的,但会被统一转换为大写存储。如果你希望保留大小写(例如字段名empName),或者使用SQL保留字作为名称,必须使用双引号括起来。上述例子中使用了双引号,因此表名EMPLOYEE会以大写形式存储,但如果创建时写的是create table Employee,最终存储的也是EMPLOYEE。我个人的习惯是,除非有强制要求,否则不使用双引号,全部用大写或小写来写SQL,避免引号带来的混乱。
  2. 表空间TABLESPACE子句指定了表数据存储在哪个表空间。达梦安装后会创建MAINSYSTEMROLL等表空间。生产环境中,合理规划表空间(如将索引和表分开、按业务分表空间)对管理和性能有帮助。对于初学者,可以先使用默认的MAIN表空间。
  3. STORAGE子句:用于精细控制表的物理存储参数,如初始大小、扩展大小。对于小型或测试系统,可以不指定,使用默认值。对于已知会非常大的表,预先设置合理的INITIALNEXT值可以减少存储碎片。

3.3 约束与索引的创建

约束保证了数据的完整性。

-- 创建表后添加约束 ALTER TABLE “EMPLOYEE” ADD CONSTRAINT “UK_EMP_EMAIL” UNIQUE (“EMAIL”); -- 唯一约束 ALTER TABLE “EMPLOYEE” ADD CONSTRAINT “FK_EMP_DEPT” FOREIGN KEY (“DEPARTMENT_ID”) REFERENCES “DEPARTMENT”(“ID”); -- 外键约束 -- 创建索引(非唯一) CREATE INDEX “IDX_EMP_DEPT” ON “EMPLOYEE”(“DEPARTMENT_ID”, “HIRE_DATE”);

关于索引的实践建议:

  • 主键和唯一约束会自动创建索引,无需手动再为这些字段建索引。
  • 达梦支持多种索引类型:B树索引(默认)、位图索引(适用于低基数字段)、函数索引等。
  • 创建复合索引时,将等值查询条件中最常用的字段放在最前面,范围查询字段放在后面。例如上例中,如果查询条件经常是WHERE DEPARTMENT_ID = ? AND HIRE_DATE > ?,那么这个索引就是高效的。
  • 不要盲目创建索引。索引会降低INSERTUPDATEDELETE的速度。通常只为高频查询的WHERE条件、JOIN关联字段和ORDER BY字段创建索引。

4. 数据操作语言(DML):增删改查的差异点

基础的INSERT,UPDATE,DELETE,SELECT语法是标准的,但达梦在一些细节和函数上有所不同。

4.1 INSERT 的多种姿势

-- 1. 标准插入 INSERT INTO EMPLOYEE (ID, EMP_NAME, SALARY) VALUES (1, ‘张三‘, 8000); -- 2. 省略字段列表(不推荐,易出错) INSERT INTO EMPLOYEE VALUES (2, ‘李四‘, 9000, SYSDATE, 10, ‘lisi@xx.com‘, NULL); -- 3. 批量插入(性能关键!) INSERT INTO EMPLOYEE (ID, EMP_NAME, DEPARTMENT_ID) SELECT 100 + ROWNUM, ‘批量员工‘ || ROWNUM, 20 FROM DUAL CONNECT BY LEVEL <= 1000; -- 插入1000条测试数据 -- 达梦也支持 INSERT ALL 语法(兼容Oracle) INSERT ALL INTO EMPLOYEE (ID, EMP_NAME) VALUES (3, ‘王五‘) INTO EMPLOYEE (ID, EMP_NAME) VALUES (4, ‘赵六‘) SELECT * FROM DUAL;

批量插入的重要性:在数据迁移或初始化时,务必使用批量插入(如上面的INSERT ... SELECT),而不是在程序循环中执行单条INSERT。单条提交会产生大量事务开销,速度可能相差百倍以上。达梦的dts(达梦迁移工具)或disql命令行工具的start transaction; ... commit;包裹多条INSERT也是批量操作。

4.2 UPDATE 与 DELETE 的注意事项

-- 更新数据 UPDATE EMPLOYEE SET SALARY = SALARY * 1.1, -- 涨薪10% HIRE_DATE = HIRE_DATE + 365 -- 日期计算 WHERE DEPARTMENT_ID = 10; -- 删除数据 DELETE FROM EMPLOYEE WHERE EMP_NAME = ‘张三‘; -- 清空表(高危操作!) TRUNCATE TABLE EMPLOYEE;

TRUNCATEvsDELETE

  • DELETE是DML操作,一行行删除,可以WHERE过滤,产生大量重做日志(Redo Log),速度慢,但可以回滚。
  • TRUNCATE是DDL操作,直接回收表的数据段(高水位线复位),不产生大量日志,速度极快,不可回滚(在达梦中,如果启用了闪回功能,可能可以恢复,但不要依赖于此)。
  • 黄金法则:清空测试数据或整个表时用TRUNCATE;删除部分业务数据时用DELETE,并务必带上WHERE条件,执行前最好先用SELECT确认要删除的数据。

4.3 SELECT 查询的核心:函数与分页

查询是SQL的重头戏。达梦内置了非常丰富的函数。

  • 字符串函数SUBSTR,INSTR,REPLACE,LENGTH(字符数),LENGTHB(字节数),UPPER,LOWER,TRIM,LPAD/RPAD等。与标准SQL基本一致。

  • 日期函数

    • SYSDATE: 当前系统日期时间。
    • ADD_MONTHS(date, n): 加减月份,处理月末日期很智能。
    • MONTHS_BETWEEN(date1, date2): 返回两个日期之间的月数。
    • LAST_DAY(date): 返回日期所在月份的最后一天。
    • TO_CHAR(date, ‘format‘): 日期转字符串,如TO_CHAR(HIRE_DATE, ‘YYYY-MM-DD HH24:MI:SS‘)
    • TO_DATE(string, ‘format‘): 字符串转日期,如TO_DATE(‘2023-10-01‘, ‘YYYY-MM-DD‘)

    注意:达梦的日期格式化模型与Oracle高度兼容。在处理字符串和日期转换时,明确指定格式符是避免错误的最佳实践。

  • 分页查询——重中之重: 分页是Web应用中最常见的需求。达梦不支持MySQL的LIMIT offset, row_count语法,也不直接支持SQL Server的OFFSET-FETCH(12c以后支持类似语法)。达梦主要支持两种分页方式:

    方法一:使用ROWNUM(兼容Oracle,最常用)ROWNUM是一个伪列,表示结果集返回的行号,从1开始。

    -- 查询第6到第15条记录(每页10条,第2页) SELECT * FROM ( SELECT T.*, ROWNUM AS RN FROM ( SELECT ID, EMP_NAME, SALARY FROM EMPLOYEE ORDER BY HIRE_DATE DESC -- 最内层:业务查询和排序 ) T WHERE ROWNUM <= 15 -- 第二层:限制上限 ) WHERE RN >= 6; -- 最外层:限制下限

    为什么需要三层嵌套?因为ROWNUM是在数据从表中取出后才分配的。WHERE ROWNUM <= 15可以筛选出前15行。但你不能直接写WHERE ROWNUM >= 6 AND ROWNUM <= 15,因为第一行ROWNUM=1不满足>=6,会被过滤掉,然后第二行变成新的ROWNUM=1,依然不满足,导致永远没有结果。所以需要先通过内层子查询固定住ROWNUM(别名为RN),再在外层用RN进行范围筛选。

    方法二:使用LIMIT ... OFFSET(DM8版本开始支持,更直观)从达梦8版本开始,为了兼容MySQL/PostgreSQL生态,增加了LIMIT子句支持。

    SELECT ID, EMP_NAME, SALARY FROM EMPLOYEE ORDER BY HIRE_DATE DESC LIMIT 10 OFFSET 5; -- 从第6行开始(OFFSET 5),取10条

    如何选择?如果你的达梦版本是8.0及以上,并且不担心对Oracle兼容性的依赖,强烈推荐使用LIMIT/OFFSET,它写法简洁,意图清晰。对于老版本或必须保证Oracle语法兼容的场景,则使用ROWNUM三层嵌套。

5. 高级查询与性能初窥

掌握了基础DML后,一些更复杂的查询和性能相关的基础概念需要了解。

5.1 连接查询(JOIN)

达梦支持标准的INNER JOIN,LEFT JOIN,RIGHT JOIN,FULL JOIN。写法与标准SQL一致。

-- 查询员工及其部门信息 SELECT E.EMP_NAME, D.DEPT_NAME FROM EMPLOYEE E LEFT JOIN DEPARTMENT D ON E.DEPARTMENT_ID = D.ID WHERE E.SALARY > 5000;

性能提示:确保JOIN条件(ON子句)上的字段有索引。上述例子中,最好在EMPLOYEE.DEPARTMENT_IDDEPARTMENT.ID上都有索引。

5.2 子查询与 EXISTS

子查询常用于WHEREFROM子句中。

-- 查询比本部门平均工资高的员工 SELECT EMP_NAME, SALARY, DEPARTMENT_ID FROM EMPLOYEE E1 WHERE SALARY > ( SELECT AVG(SALARY) FROM EMPLOYEE E2 WHERE E2.DEPARTMENT_ID = E1.DEPARTMENT_ID -- 关联子查询 ); -- 使用EXISTS检查存在性(通常性能优于IN) SELECT * FROM DEPARTMENT D WHERE EXISTS ( SELECT 1 FROM EMPLOYEE E WHERE E.DEPARTMENT_ID = D.ID );

关于INvsEXISTS:对于大数据集,如果子查询结果集小,而主查询结果集大,EXISTS通常效率更高(因为它找到一条匹配就返回)。反之,如果子查询结果集大,主查询结果集小,IN可能更合适。但这不是绝对的,实际执行计划取决于优化器。一个通用建议是:如果子查询能返回大量重复值,使用EXISTS;如果子查询结果集很小且唯一,两者差别不大,IN的写法可能更直观。

5.3 聚合与分组(GROUP BY)

-- 按部门统计人数和平均工资 SELECT DEPARTMENT_ID, COUNT(*) AS EMP_COUNT, AVG(SALARY) AS AVG_SALARY, SUM(SALARY) AS TOTAL_SALARY FROM EMPLOYEE WHERE HIRE_DATE > DATE ‘2020-01-01‘ GROUP BY DEPARTMENT_ID HAVING AVG(SALARY) > 8000 -- 对分组后的结果进行过滤 ORDER BY AVG_SALARY DESC;

WHEREvsHAVING:记住一个简单规则——WHERE在分组前过滤行,HAVING在分组后过滤组WHERE子句中不能使用聚合函数(如AVG(SALARY)),而HAVING可以。

5.4 视图的创建与使用

视图是一个虚拟表,基于SQL查询结果。

-- 创建一个视图 CREATE OR REPLACE VIEW V_EMP_DEPT AS SELECT E.ID, E.EMP_NAME, E.SALARY, D.DEPT_NAME FROM EMPLOYEE E JOIN DEPARTMENT D ON E.DEPARTMENT_ID = D.ID; -- 像使用普通表一样查询视图 SELECT * FROM V_EMP_DEPT WHERE DEPT_NAME = ‘研发部‘;

视图的作用:简化复杂查询、提供数据安全层(只暴露视图中的字段)、保证逻辑一致性。需要注意的是,视图不存储数据,每次查询视图都会执行其背后的SQL语句。对于复杂的视图,可能会影响性能。

6. 事务控制与锁的初步理解

数据库事务是保证数据一致性的核心机制。达梦默认采用读已提交(READ COMMITTED)的隔离级别。

6.1 基本事务控制

-- 显式事务控制 START TRANSACTION; -- 或 BEGIN UPDATE ACCOUNT SET BALANCE = BALANCE - 100 WHERE USER_ID = ‘A‘; UPDATE ACCOUNT SET BALANCE = BALANCE + 100 WHERE USER_ID = ‘B‘; -- 此时其他会话看不到这两个UPDATE的结果 COMMIT; -- 提交事务,变更永久生效 -- 或 ROLLBACK; -- 回滚事务,所有变更撤销

在达梦的图形工具或DBeaver中,通常默认是自动提交(AUTOCOMMIT)模式,即每条SQL语句都是一个独立的事务。在执行批量数据操作时,务必关闭自动提交,使用显式事务,将多个操作包裹在BEGINCOMMIT之间,这不仅能保证原子性,还能大幅提升性能(减少日志刷盘次数)。

6.2 锁的简单认知与查询

当多个会话同时操作同一行数据时,锁机制防止数据混乱。达梦有行级锁、表级锁等。

  • UPDATEDELETESELECT ... FOR UPDATE语句会对涉及的行加上排他锁(X锁)。
  • 普通的SELECT语句在READ COMMITTED级别下不加锁,读取已提交的最新数据。

如何查询当前锁信息?这是排查“锁等待”或“死锁”问题的关键。达梦提供了系统视图V$LOCKV$TRX来查看。

-- 查看当前锁信息(需要DBA权限) SELECT * FROM V$LOCK; -- 查看当前活动事务 SELECT * FROM V$TRX; -- 一个更实用的查询,查看谁锁住了谁 SELECT l.sess_id AS 阻塞会话ID, s.sess_seq AS 会话序列号, s.sql_text AS 正在执行的SQL, l.blocked AS 被阻塞的会话ID FROM V$LOCK l JOIN V$SESSIONS s ON l.sess_id = s.sess_id WHERE l.blocked > 0; -- blocked字段大于0表示该会话阻塞了其他会话

如果你遇到一个SQL执行很久没反应,或者应用报“锁超时”错误,就可以通过这些视图来定位是哪个会话持有了锁,进而分析其SQL语句,判断是正常长事务还是异常锁等待。

避免长事务:长时间不提交的事务会持有锁,阻塞其他操作。在应用程序中,确保事务范围尽可能小,尽快提交或回滚。不要在事务内进行耗时的人工操作(如等待用户输入)。

7. 达梦SQL编写习惯与优化入门

最后,分享几个从其他数据库迁移到达梦,或在达梦上开发时需要养成的习惯和优化入门知识。

7.1 养成大小写一致的习惯

如前所述,达梦默认不区分对象名大小写并转为大写。为了避免混乱,建议团队统一规范:

  • 方案A(推荐):所有SQL关键字大写,对象名和字段名小写(或大小写混合的驼峰命名),并且在创建对象时不使用双引号。这样在数据库中统一存储为大写,编写时用小写查询也能匹配。select * from employee;
  • 方案B:如果确需保留大小写,则所有地方(创建、查询)都严格使用双引号select * from “Employee”;切忌混用,否则会出现“表或视图不存在”的错误。

7.2 使用绑定变量提升性能

这是编写高性能达梦SQL(乃至任何数据库SQL)的黄金法则。不好的写法(硬解析)

// 在循环中拼接SQL for (int id : idList) { String sql = “SELECT * FROM EMPLOYEE WHERE ID = ” + id; // 每次循环,数据库都要对全新的SQL字符串进行解析、优化,开销巨大。 }

好的写法(软解析)

String sql = “SELECT * FROM EMPLOYEE WHERE ID = ?”; PreparedStatement pstmt = connection.prepareStatement(sql); for (int id : idList) { pstmt.setInt(1, id); // 数据库只需对带“?”的SQL解析一次,后续只需传递参数值,性能极大提升。 }

达梦的优化器会对带绑定变量的SQL进行缓存,大大减少解析开销,同时还能防止SQL注入攻击。

7.3 初识执行计划

当你发现某条SQL很慢时,第一反应应该是查看它的“执行计划”。执行计划是数据库优化器决定的执行路径,告诉你它将如何访问数据(全表扫描?索引扫描?),以及操作的代价。 在达梦管理工具或DBeaver中,通常有“解释计划”或“执行计划”的功能按钮。你也可以使用SQL命令:

EXPLAIN SELECT * FROM EMPLOYEE WHERE DEPARTMENT_ID = 10 AND SALARY > 5000;

或者更详细地:

CALL SP_EXPLAIN_INIT(); -- 初始化 EXECUTE IMMEDIATE ‘SELECT * FROM EMPLOYEE WHERE DEPARTMENT_ID = 10 AND SALARY > 5000‘; SELECT * FROM EXPLAIN; -- 查看计划

看执行计划是个专业活,但初学者可以关注几个关键点:

  1. CSCN2(全表扫描):如果对大表出现了这个,且没有有效的WHERE条件,通常意味着性能瓶颈。考虑为过滤字段添加索引。
  2. SSEK2(二级索引扫描)CSEK2(聚簇索引扫描):这通常是好的,表示使用了索引。
  3. 代价(COST):数值越大,预估成本越高。对比不同SQL或不同索引下的COST值,有助于判断。
  4. 操作顺序:从最内层(缩进最多)往最外层看,了解数据的获取流程。

7.4 慢SQL优化的第一步:索引与避免全表扫描

大多数慢SQL的根源在于不必要的“全表扫描”(FULL TABLE SCAN)。

  • 为高频查询条件创建索引:分析你的应用SQL,找出WHEREJOIN ONORDER BY子句中最常出现的字段组合,为其创建复合索引。
  • 避免在索引列上使用函数或运算WHERE UPPER(name) = ‘ABC‘会使索引失效。如果必须这样做,可以考虑创建函数索引:CREATE INDEX IDX_UPPER_NAME ON EMPLOYEE(UPPER(EMP_NAME));
  • 谨慎使用SELECT *:只查询需要的字段。特别是当表中有CLOBBLOB等大字段时,SELECT *会带来巨大的网络和内存开销。
  • 注意LIKE查询LIKE ‘ABC%‘(前缀匹配)可以使用索引,但LIKE ‘%ABC‘(后缀匹配)或LIKE ‘%ABC%‘(前后模糊)会导致索引失效,在数据量大时性能极差。考虑使用全文索引或其他搜索方案。

掌握这些基础,你已经能够应对达梦数据库80%的日常开发任务。真正的精通来自于在复杂场景下的实践、对执行计划的深入分析以及对达梦特有参数和特性的持续学习。记住,把达梦当作一个熟悉而又陌生的朋友,尊重它的特性,你就能和它高效合作。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/6 1:05:07

带隙基准源设计:从原理到实践的温度补偿与电路实现

1. 项目概述&#xff1a;为什么我们需要一个“不随温度变化的电压”&#xff1f;在模拟电路和混合信号芯片设计的核心地带&#xff0c;有一个看似简单却至关重要的模块&#xff1a;电压基准源。想象一下&#xff0c;你正在设计一个高精度的温度传感器&#xff0c;或者一个需要将…

作者头像 李华
网站建设 2026/8/6 1:04:16

论文写作瓶颈突破!gradpaper学术工具好用又靠谱

Gradpaper-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/课程论文。Gradpaper论文智能生成软件&#xff0c;10分钟生成万字毕业论文、期刊论文、文献综述、PPT&#xff0c;Agc查重、降重报告、文献资料。只需一个标题&#xff0c;从开题报告到答辩一键生成软件&a…

作者头像 李华
网站建设 2026/8/6 1:00:01

联想笔记本BIOS隐藏设置终极指南:3分钟解锁全部高级功能

联想笔记本BIOS隐藏设置终极指南&#xff1a;3分钟解锁全部高级功能 【免费下载链接】LEGION_Y7000Series_Insyde_Advanced_Settings_Tools 支持一键修改 Insyde BIOS 隐藏选项的小工具&#xff0c;例如关闭CFG LOCK、修改DVMT等等 项目地址: https://gitcode.com/gh_mirrors…

作者头像 李华
网站建设 2026/8/6 0:52:53

政务外网环境下视频监控资源整合:新增仓库接入实施方案

一、现状本项目处于政务外网严格的网络边界环境内。原仓库视频监控系统已稳定运行&#xff0c;包含13路存量监控点位&#xff0c;覆盖主要出入口及核心库区。二、需求接入策略与技术路线&#xff1a; 针对本次新建的12路监控摄像头&#xff0c;将严格遵循政务外网接入规范&…

作者头像 李华
网站建设 2026/8/6 0:43:49

ZGI Runtime:切换模型后 Agent 为什么失效?

切换模型后 Agent 失效&#xff0c;常见原因落在任务契约&#xff1a;字段格式变了&#xff0c;工具参数没有通过校验&#xff0c;长资料被截断&#xff0c;错误返回也和原模型不同。迁移前需要固定输入、输出、工具协议与验收样本&#xff0c;再逐层检查差异。ZGI Runtime 把模…

作者头像 李华
网站建设 2026/8/6 0:32:51

终极指南:3步掌握ACOLITE大气校正的LUT文件获取

终极指南&#xff1a;3步掌握ACOLITE大气校正的LUT文件获取 【免费下载链接】acolite ACOLITE: generic atmospheric correction module 项目地址: https://gitcode.com/gh_mirrors/ac/acolite ACOLITE是一款强大的开源卫星遥感大气校正工具&#xff0c;专为沿海和内陆水…

作者头像 李华