初识达梦数据库是在今年四月的北京DTCC会议,看到了前来参加会议的国产数据库厂商来自武汉,确实有些兴奋,毕竟身为湖北人的,并且在武汉上大学,在那里度过了一些非常美好和无法忘却的日子,特意上前和达梦工作人员聊了聊,巧合的是这位工作人员还是我的师姐,顿时对达梦的亲切感更加一层。近来看了itpub上的达梦的帖子,大家都很支持达梦,也感受到了达梦人对与国产数据库的执着以及对梦想的追求精神。工作中虽说用不到,还是下了个开发版学习一下,以初学者的角度来记录这个过程,与大家分享。
主要看看达梦的索引和执行计划相关的内容,实验的具体环境如下:
操作系统:Windows XP sp2
数据库版本:DM6.0开发版
在安装好dm6.0后(过程略,参照安装文档没有遇到错误,由于仅仅是初体验,安装和配置均为默认的设置),新建一个数据库TEST,用户TEST,授予dba和resource权限。这些过程都可以通过gui来完成,初识dm很容易发现dm的gui做的有点像sqlserver,基本不用看文档就可以直接做一些基本的操作。
找到交互式工具isql后,使用test登录,在工具/选项里面简单设置了一些编辑器和数据库选项,把自动提交取消掉。
create table t_test(id number, name varchar2(20));
rollback;
select * from t_test a;
全部运行成功,第一句的创建表的语句还有数据类型完全是和oracle一样的。然后做一个rollback,成功后查询这个表的内容,也可以成功,可以看出DDL是自动提交的,这个和oracle类似。
在数据库TEST的模式下查看SYSDBA下面的系统表,发现表的命名还是比较熟悉的,找到了systables和sysindexes,初步判断应该是和oracle里面的dba_tables还有dba_indexes类似,存放了表和索引的一些信息,大致看看字段,有表id,表名name,表类型type,填充因子fillfactor,limit_space空间的限制,而resvd1等列暂时没有通过列名猜出(后面可以推出应该是行数,即oracle里面的numrows)。
接下来实验一下这两个系统表在创建表和索引时的情况。
--使用基表sysdba.sysindexes创建测试数据表
create table t_dm_test1 as
select * from sysdba.sysindexes a ;
--索引id上创建唯一索引
create unique index indx_dm_test1__id on t_dm_test1 (id);
--在表id上创建普通btree索引
create index indx_dm_test1__tableid on t_dm_test1(tableid);
--在索引类型type上创建bimap索引
create bitmap index bt_indx_dm_test1__type on t_dm_test1(type);
isql的gui没有类似plsql dev上的command窗口,于是开一个isql命令行,便于贴上输出信息:
E:\dm\bin>isql
isql V6.0.2.69-Build(2010.07.08)
SQL>login
server name:localhost
user name:test
password:
port:12345
login succeed! dm_login time used:32.834(ms)
SQL>select
2 a.name,
3 a.id,
4 a.type,
5 a.resvd1
6 from
7 sysdba.systables a
8 where
9 a.name = upper('t_dm_test1');
select
a.name,
a.id,
a.type,
a.resvd1
from
sysdba.systables a
where
a.name = upper('t_dm_test1');
name id type resvd1
1 t_dm_test1 1004 U 86
1 rows got
time used: 0.977(ms) clock tick:2545936.
SQL>
可以看到systables已经有了这个表的相关信息,从结果中获得table的id是1004,很容易联想sysindexes会有一个table的id与此关联,于是来看一下表上的索引情况:
SQL>select
2 a.name,
3 a.isunique,
4 a.isdata,
5 a.rootpage,
6 a.type,
7 a.xtype,
8 a.resvd1
9 from
10 sysdba.sysindexes a
11 where a.tableid = 1004;
12 /
select
a.name,
a.isunique,
a.isdata,
a.rootpage,
a.type,
a.xtype,
a.resvd1
from
sysdba.sysindexes a
where a.tableid = 1004;
name isunique isdata rootpage
type xtype resvd1
1 INDEX33555489 Y Y 1440 BT 16
0
2 indx_dm_test1__id Y N 1456 BT 17
0
3 indx_dm_test1__tableid N N 1472 BT 1
0
4 bt_indx_dm_test1__type N N 1488 BM 1
0
4 rows got
time used: 0.495(ms) clock tick:1286565.
SQL>
这里可以看到新创建的三个索引,类型分别是BT(btree)或BM(bitmap),isunique说明是否是唯一索引,rootpage是根块数,xtype(仅仅给出,未知)。可以看到还有一个INDEX33555489这个索引,看起来像是系统自动加上去的,翻阅了随机的dm的dm_dba.sql发现DM的所有表都是以聚簇索引来组织的,利用B树机制存储索引条目,以保证用最短路径访问键值。(前面黑体引自《达梦数据库管理系统DM 系统管理员手册》)
下面来看看不同查询的访问路径:
1, 全表扫描
SQL>explain select * from t_dm_test1 a ;
explain select * from t_dm_test1 a ;
#RSET:[2, 1, 86];
#CSEK:[2, 1, 86]; INDEX33555489(t_dm_test1), FULL_SCAN
time used: 4.927(ms) clock tick:12858194.
SQL>
对oracle的执行计划比较熟悉,类推一下dm的执行计划, CSEK代表数据从表获得索引中获取,后面的参数没有找到相关文档,但可以猜测,86是可能的返回numrows,前面的2,1可能是类似于开销之类的值,随后的INDEX33555489就是前面查询中表上系统自动创建的(以rowid创建的聚簇索引),FULL_SCAN代表全扫描。
2, 唯一索引查找
SQL>explain select * from t_dm_test1 a where a.id = 1;
explain select * from t_dm_test1 a where a.id = 1;
#RSET:[1, 1, 1];
#CSEK(SECOND):[1, 1, 1]; indx_dm_test1__id(t_dm_test1), INDEX_EQU_SEARCH
time used: 0.422(ms) clock tick:1097723.
SQL>
使用了id列上的唯一索引indx_dm_test1__id,方式为INDEX_EQU_SEARCH,猜测这个是index equal search,这个执行计划还是比较合理的。
3, 索引范围查找
SQL>explain select * from t_dm_test1 a where a.id > 1;
explain select * from t_dm_test1 a where a.id > 1;
#RSET:[1, 1, 1];
#CSEK(SECOND):[1, 1, 1]; indx_dm_test1__id(t_dm_test1), INDEX_G_SEARCH
time used: 1.069(ms) clock tick:2786753.
SQL>
这里的id>1应该是取全部数据,可能是优化器不知道表中的数据分布,这里只是按照规则来选取了INDEX_G_SEARCH。这个执行计划可能看起来就不是最好的了,不过实验数据量太小不能用来做详细的性能对比的测试。(暂时没有找到收集列数据分布信息的过程或者命令)
4, 使用bimap
SQL>explain select id from t_dm_test1 a where a.type = 'U';
2 /
explain select id from t_dm_test1 a where a.type = 'U';
#RSET:[1, 1, 1];
#CSEK(SECOND):[1, 1, 1]; bt_indx_dm_test1__type(t_dm_test1), INDEX_EQU_S
EARCH
time used: 0.363(ms) clock tick:944993.
SQL>
看了一下数据,这个表内的数据只有U和S,猜测S代表系统,U代表用户,因此适合创建bitmap索引,我想这个原理也应该和oracle类似。
使用记录先暂且到这里,最后说一下初次使用时觉得不太习惯的地方:
1,sql结果集导出只有三种格式选项,常用的csv没有。
2,没有仔细看dm的事务原理,新建一个查询只要有修改,在退出isql的时候都会提示需要提交或者回滚,不太习惯。
3,使用isql格式化的时候plqsl块的格式如下:
declare
v_extents int:=0;
v_pages int:=0;
v_used int:=0;
begin
sp_get_table_info(
'TEST',
'TEST',
upper('t_test_index_table'),
v_extents,
v_pages,
v_used
);
print(v_extents||'-'||v_pages||'-'||v_used);
end;
看起来不大习惯,begin和end缩进太多了。
4,Dm的Print()和oracle的dbms_output.put_line()区别还是有的,不知道达梦有没有注意到:
SQL>begin
2 print('name'||'');
3 end;
4 /
begin
print('name'||'');
end;
name
0 rows affected
time used: 5.999(ms) clock tick:15657927.
SQL>begin
2 print('name'||null);
3 end;
4 /
begin
print('name'||null);
end;
NULL
0 rows affected
time used: 2.424(ms) clock tick:6322566.
或者使用print('name'+null);也是同样的情况。
而oracle的情况如下:
SQL> begin
2 dbms_output.put_line('asd'||''||null);
3 end;
4 /
asd
PL/SQL procedure successfully completed
SQL> begin
2 dbms_output.put_line('asd'+null);
3 end;
4 /
PL/SQL procedure successfully completed
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/16179598/viewspace-669392/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/16179598/viewspace-669392/