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

相关推荐
保定公民4 天前
达梦DMDRS数据库同步用户最小权限
数据库·达梦·达梦数据库·数据同步·dm·dmdrs
liwenzhen200510 天前
DM SQL 排序优化-消除排序
排序·sort·dm
liwenzhen200515 天前
DM 修改dm.ini 参数
dm·dm.ini·达梦数据库参数文件
liwenzhen200515 天前
DM 使用DBMS_SQLTUNE 系统包查看SQL 执行计划
执行计划·dm·dbms_sqltune
liwenzhen200517 天前
DM 行级锁
行级锁·dm
liwenzhen200517 天前
DM 配置 unixODBC
odbc·dm
liwenzhen20051 个月前
DM 常用 HINT 参考
dm·hint
liwenzhen20051 个月前
DM SQL 排序优化
dm·sql 排序优化
liwenzhen20051 个月前
DMDRS 配置
dm·drs