执行计划:问题SQL:查询 900w 条数据,运行 33s 左右。
SQL> select * from test order by name desc;
执行计划:
1 #NSET2: [375085, 900w, 1049]
2 #PRJT2: [375085, 900w, 1049]; exp_num(30), is_atom(FALSE)
3 #SORT3: [375085, 900w, 1049]; key_num(1), partition_key_num(0), is_distinct(FALSE), top_flag(0), is_adaptive(0)
4 #CSCN2: [3198, 900w, 1049]; INDEXxx(TEST); btr_scan(1)
ET 输出:
NSET2 2 0% 5 1 2 0 0 0 0 NULL NULL 0
DLCK 5 0% 4 0 1 0 0 0 0 NULL NULL 0
PRJT2 7 0% 3 2 2 0 0 0 0 NULL NULL 0
CSCN2 6503249 20.09% 2 4 31985 0 0 0 0 NULL NULL 0
SORT3 25874272 79.91% 1 3 31986 30720 9827306 0 0 NULL NULL 0
上面的数据显示,SQL 的时间主要用在排序上。
调整:去掉排序,运行 0.066s 左右。
SQL> select * from test;
调整的执行计划:
1 #NSET2: [3198, 900w, 1049]
2 #PRJT2: [3198, 900w, 1049]; exp_num(30), is_atom(FALSE)
3 #CSCN2: [3198, 900w, 1049]; INDEXxx(TEST); btr_scan(1)
调整1的ET 输出:
NSET2 1 0.37% 4 1 2 0 0 0 0 NULL NULL 0
DLCK 4 1.49% 2 0 1 0 0 0 0 NULL NULL 0
PRJT2 4 1.49% 2 2 2 0 0 0 0 NULL NULL 0
CSCN2 259 96.64% 1 3 1 0 0 0 0 NULL NULL 0
验证了,排序是主要问题。
问题分析思路:
检查排序字段 NAME 是有索引的,但是索引的是默认的升序,而SQL 使用的是降序,所以需要耗费很久进行排序。
CREATE OR REPLACE INDEX "AA"."BB" ON "AA"."TEST"("NAME" ASC)
解决办法:
将索引以降序的排列方式重建:
CREATE OR REPLACE INDEX "AA"."BB" ON "AA"."TEST"("NAME" DESC)
再次执行问题SQL,运行 0.063s 左右。
重建索引后的执行计划:
1 #NSET2: [3198, 900w, 1049]
2 #PRJT2: [3198, 900w, 1049]; exp_num(30), is_atom(FALSE)
3 #BLKUP2: [3198, 900w, 1049]; BB(TEST)
4 #SSCN: [3198, 900w, 1049]; BB(TEST); btr_scan(1); is_global(0)
重建索引后的ET:
NSET2 1 0.09% 5 1 2 0 0 0 0 NULL NULL 0
PRJT2 4 0.37% 4 2 2 0 0 0 0 NULL NULL 0
DLCK 6 0.56% 3 0 1 0 0 0 0 NULL NULL 0
SSCN 29 2.69% 2 4 1 0 0 0 0 NULL NULL 0
BLKUP2 1037 96.29% 1 3 2 0 0 0 0 NULL NULL 0
欢迎访问达梦技术分享社区 ECO