问题:一张表,有1亿行数据,两列:oldaccountid,newaccountid,都是int,要求前台可以根据oldaccountid查newaccountid,也可以根据newaccountid查oldaccountid,要求提供最优化的方式,加速查询时间。
我闲来无事,正好试验一下,服务器配置,XEON 5138,4核,16G内存。
1.创建表
create table test (id1, id2)
2. 注入数据
db2 +c alter table test1 activate not logged initially
db2 +c "begin atomic declare i int default 0; while i<1000000 do insert into test1 values (int(rand()*1000000),int(rand()*1000000)); set i=i+1;end while; end"
3 查询无索引效率
开启解释模式
db2 set current explain mode explain
创建查询语句
db2inst@linux34:~> cat query.sql
select id1 from test where id2=9999;
db2inst@linux34:~> cat query1.sql
select id2 from test where id1=333333;
创建解释表
db2 -tvf EXPLAIN.DDL
执行查询
db2 -tvf query.sql
db2 -tvf.query1.sql
查看解释计划
db2inst@linux34:~> db2exfmt -l -d sample -o query_exfmt(1).out
(query.sql, query1.sql解释计划一样)
Optimized Statement:
-------------------
SELECT Q1.ID1 AS "ID1"
FROM DB2INST.TEST AS Q1
WHERE (Q1.ID2 = 9999)
Access Plan:
-----------
Total Cost: 2981.82
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
1.46672
TBSCAN
( 2)
2981.82
2464
|
1e+06
TABLE: DB2INST
TEST
Q1
Extended Diagnostic Information:
--------------------------------
No extended Diagnostic Information for this statement.
Plan Details:
-------------
1) RETURN: (Return Result)
Cumulative Total Cost: 2981.82
Cumulative CPU Cost: 2.18226e+09
创建双单索引
create index id1_idx test(id1);
create index id2_idx test(id2);
再次执行两条语句,查看执行计划query_exfmt2.out
Optimized Statement:
-------------------
SELECT Q1.ID2 AS "ID2"
FROM DB2INST.TEST AS Q1
WHERE (Q1.ID1 = 333333)
Access Plan:
-----------
Total Cost: 22.7018
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
1.52582
FETCH
( 2)
22.7018
3
/---+----
1.52582 1e+06
IXSCAN TABLE: DB2INST
( 3) TEST
15.1382 Q1
2
|
1e+06
INDEX: DB2INST
ID1_IDX
Q1
Extended Diagnostic Information:
--------------------------------
可以看出双索引,执行计划提升100倍以上。
我删除了双单索引,创建复合索引
create index cid_idx test(id1, id2);
再次执行查询计划,query_exfmt3.out
-------------------
SELECT Q1.ID2 AS "ID2"
FROM DB2INST.TEST AS Q1
WHERE (Q1.ID1 = 333333)
Access Plan:
-----------
Total Cost: 15.1383
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
1.52582
IXSCAN
( 2)
15.1383
2
|
1e+06
INDEX: DB2INST
CID_IDX
Q1
Extended Diagnostic Information:
--------------------------------
id1在前的复合索引,比双单索引用id1查id2更快一点,但是效果不明显
用(id1, id2)复合索引用id2查id1,看解释计划query_exfmt4.out
Optimized Statement:
-------------------
SELECT Q1.ID1 AS "ID1"
FROM DB2INST.TEST AS Q1
WHERE (Q1.ID2 = 9999)
Access Plan:
-----------
Total Cost: 2981.82
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
1.46672
TBSCAN
( 2)
2981.82
2464
|
1e+06
TABLE: DB2INST
TEST
Q1
Extended Diagnostic Information:
虽然有复合索引,但是id1在复合索引首位的化,用id2做谓词去查,效果和全表扫描一样,没有优化。
我又尝试创建了10个表空间,然后创建表分区,效果还不如双索引,而且管理复杂度上升,解释计划略。
所以,对于1亿行表,每行只有两列字段的表,id1查id2, id2查id1,在两列上建立单索引,是最佳选择。
添加新评论25 条评论
2015-01-05 17:44
2014-06-06 11:13
2014-05-13 22:42
另外要考虑的也不止这些;所以综合来说我会比较倾向于楼主最初的那个结论。
2014-05-12 13:51
2014-05-12 07:59
create index id1_idx test(id1) include (id2);
create index id2_idx test(id2) include (id1);
这个应该是要unique才能创建的
2014-05-11 18:51
create index id1_idx test(id1) include (id2);
create index id2_idx test(id2) include (id1);
这个应该是要unique才能创建的吧?
2014-05-09 13:44
create index id1_idx test(id1) include (id2);
create index id2_idx test(id2) include (id1);
能省下来索引扫描后再去表里面找另外一
2014-05-09 13:39
create index id1_idx test(id1) include (id2);
create index id2_idx test(id2) include (id1);
能省下来索引扫描后再去表里面找另外一
2014-05-09 13:21
2014-05-09 13:20
2014-05-09 09:48
2014-05-08 21:33
create index id1_idx test(id1) include (id2);
create index id2_idx test(id2) include (id1);
能省下来索引扫描后再去表里面找另外一
2014-05-08 21:30
create index id1_idx test(id1) include (id2);
create index id2_idx test(id2) include (id1);
能省下来索引扫描后再去表里面找另外一个ID的那步。
2014-05-08 20:46
是“1e+06”
如果是1000000行的话,这个数据量不是很大,每列平均长度是6,两列12
那就是1,000,000
2014-05-08 14:59
这个场景里肯定没啥用。
2014-05-08 14:56
是“1e+06”
如果是1000000行的话,这个数据量不是很大,每列平均长度是6,两列12
那就是1,000,000 * 12 = 12 MB。
这个数据量用来做查询性能的对比,好像小了些。
如果搞个几百兆或者几个G的数据,应该就可以验证出 分区表+两个分区索引 的优势了。
对于基于这个数据量得出的结论(两个单索引最优),这也是没问题的。
还有一点,这只是针对这个场景(两列相互查询)的。
2014-05-08 08:18
2014-05-08 07:42
2014-05-06 11:15
2014-05-06 10:59
2014-05-06 10:00
2014-05-05 14:10
2014-05-04 12:04
2014-04-30 17:30
2014-04-29 22:29