DM 收集统计信息后内存中的SQL 执行计划无效测试

1. 创建测试表并插入有特殊数据分布的数据

-- 创建测试表

复制代码
CREATE TABLE DM_STATS_TEST (
    id INT,
    category VARCHAR(10),
    value INT);

-- 插入1000行数据,制造特殊分布:

  1. category='A':990行(占99%)

  2. category='B':10行(占1%)

    INSERT INTO DM_STATS_TEST
    SELECT LEVEL, 'A', LEVEL FROM DUAL CONNECT BY LEVEL <= 990
    UNION ALL
    SELECT 990+LEVEL, 'B', 1000+LEVEL FROM DUAL CONNECT BY LEVEL <= 10;
    COMMIT;

在 CATEGORY 字段上创建一个索引

复制代码
CREATE OR REPLACE INDEX "EXAM"."IDX_CATEGORY" ON "EXAM"."DM_STATS_TEST"("CATEGORY" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;

2. 执行一个查询并查看执行计划

复制代码
SELECT * FROM DM_STATS_TEST WHERE CATEGORY =:VAR;
<===查询 B

1   #NSET2: [1, 25, 68] 
2     #PRJT2: [1, 25, 68]; exp_num(4), is_atom(FALSE) 
3       #BLKUP2: [1, 25, 68]; IDX_CATEGORY(DM_STATS_TEST)
4         #SSEK2: [1, 25, 68]; scan_type(ASC), IDX_CATEGORY(DM_STATS_TEST), scan_range[exp_param(no:0),exp_param(no:0)], is_global(0)·

SELECT PLN_ADDR,HASH_VALUE,SQLSTR,RT_METHOD,N_SUBPLNS,PHD_TIME FROM V$SQL_PLAN WHERE SQLSTR LIKE '%SELECT * FROM DM_STATS_TEST WHERE CATEGORY%' 
and lower(SQLSTR) NOT LIKE '%v$%';

PLN_ADDR			HASH_VALUE	SQLSTR												RT_METHOD			N_SUBPLNS	PHD_TIME
0x00000000797F7810	315894334	SELECT * FROM DM_STATS_TEST WHERE CATEGORY =:VAR;	0x00000000797F7E28	0	2026-01-06 15:37:00

3 - 使用常用方式收集的统计信息

复制代码
DBMS_STATS.GATHER_TABLE_STATS('EXAM','DM_STATS_TEST',null,100,TRUE,'FOR ALL COLUMNS SIZE AUTO',2);

4 - 再次执行相同查询并查看执行计划

复制代码
SELECT * FROM DM_STATS_TEST WHERE CATEGORY =:VAR;
<===查询 B

1   #NSET2: [1, 500, 68] 
2     #PRJT2: [1, 500, 68]; exp_num(4), is_atom(FALSE) 
3       #SLCT2: [1, 500, 68]; DM_STATS_TEST.category = exp_param(no:0) SLCT_PUSHDOWN(TRUE)
4         #CSCN2: [1, 1000, 68]; INDEX33555640(DM_STATS_TEST) NEED_SLCT(TRUE); btr_scan(1)

SELECT PLN_ADDR,HASH_VALUE,SQLSTR,RT_METHOD,N_SUBPLNS,PHD_TIME FROM V$SQL_PLAN WHERE SQLSTR LIKE '%SELECT * FROM DM_STATS_TEST WHERE CATEGORY%' 
and lower(SQLSTR) NOT LIKE '%v$%';

PLN_ADDR			HASH_VALUE	SQLSTR												RT_METHOD			N_SUBPLNS	PHD_TIME
0x00000000797F7810	315894334	SELECT * FROM DM_STATS_TEST WHERE CATEGORY =:VAR;	0x00000000797F7E28	0	2026-01-06 15:37:00

5 - 指定执行计划失效的统计信息

复制代码
begin
DBMS_STATS.GATHER_TABLE_STATS (
ownname => 'EXAM',
tabname => 'DM_STATS_TEST',
method_opt =>'FOR ALL COLUMNS SIZE AUTO',
granularity => 'ALL',
no_invalidate=>FALSE,
cascade => true,
force => true);
end;
/

6 - 直接检查内存中的执行计划

复制代码
SELECT PLN_ADDR,HASH_VALUE,SQLSTR,RT_METHOD,N_SUBPLNS,PHD_TIME FROM V$SQL_PLAN WHERE SQLSTR LIKE '%SELECT * FROM DM_STATS_TEST WHERE CATEGORY%' 
and lower(SQLSTR) NOT LIKE '%v$%';

空   <===其实到这就说明执行计划已经并清除了。

7 - 再次执行相同查询并查看执行计划

复制代码
SELECT * FROM DM_STATS_TEST WHERE CATEGORY =:VAR;
<===查询 B

1   #NSET2: [1, 500, 68] 
2     #PRJT2: [1, 500, 68]; exp_num(4), is_atom(FALSE) 
3       #SLCT2: [1, 500, 68]; DM_STATS_TEST.category = exp_param(no:0) SLCT_PUSHDOWN(TRUE)
4         #CSCN2: [1, 1000, 68]; INDEX33555640(DM_STATS_TEST) NEED_SLCT(TRUE); btr_scan(1)

SELECT PLN_ADDR,HASH_VALUE,SQLSTR,RT_METHOD,N_SUBPLNS,PHD_TIME FROM V$SQL_PLAN WHERE SQLSTR LIKE '%SELECT * FROM DM_STATS_TEST WHERE CATEGORY%' 
and lower(SQLSTR) NOT LIKE '%v$%';

PLN_ADDR			HASH_VALUE	SQLSTR												RT_METHOD			N_SUBPLNS	PHD_TIME
0x0000000079720A10	315894334	SELECT * FROM DM_STATS_TEST WHERE CATEGORY =:VAR;	0x0000000079721028	0	2026-01-06 15:46:54

欢迎访问达梦技术分享社区 ECO

https://eco.dameng.com

相关推荐
遇雪长安14 天前
高通安卓设备DIAG端口启用指南
android·adb·usb·dm·qpst·diag·qxdm
装不满的克莱因瓶18 天前
【国产信创】SQLark连接达梦数据库详细教程
数据库·信创·国产化·达梦数据库·dm·sqlark
保定公民2 个月前
达梦DMDRS数据库同步用户最小权限
数据库·达梦·达梦数据库·数据同步·dm·dmdrs
liwenzhen20052 个月前
DM SQL 排序优化-消除排序
排序·sort·dm
liwenzhen20052 个月前
DM 修改dm.ini 参数
dm·dm.ini·达梦数据库参数文件
liwenzhen20052 个月前
DM 使用DBMS_SQLTUNE 系统包查看SQL 执行计划
执行计划·dm·dbms_sqltune
liwenzhen20052 个月前
DM 行级锁
行级锁·dm
liwenzhen20052 个月前
DM 配置 unixODBC
odbc·dm
liwenzhen20053 个月前
DM 常用 HINT 参考
dm·hint