如何加快查询的速度?
Question:为什么在一个有30000条记录并且建立有索引的表进行操作很慢,怎么办?
30000条记录并不是太多,你会感觉有慢不应该是记录数太多的缘故,原因可能是每条记录太长,或者你的机器的性能十分低,不过还是有一些方法可能会对性能有所帮助:
1.更新统计信息(update satistics on tablename),这很容易作,并且有可能会带来性能的提高。
2.删除,然后再重新创建索引。这样作能够增加索引的连续性。但是要求是DBA或者有创建索引的权限。
3.ALTER INDEX idxname TO CLUSTER: 这样作的目的是重新创建表并且通过索引来重新排列记录。结果是强制使记录在逻辑上连续,并且提高物理上的连续性。这样作的代价最大,但是效果最好。但是,一个表中只能有一个cluster index,并且,重新排列记录可能会强迫其他的查询使用其他的索引。作这种工作,你必须要为DBA或者有alter table 的权限。并且请注意,在你运行cluster index的时候,你必须要有足够的空间,因为在为一个表创建cluster index的时候,会拷贝表中所有的记录到一个临时表中,在临时表中进行排序操作,然后会删除原来的表,然后将临时表的名字改为原始表的名字。因此,如果这个表中的数据变化很大,如经常要进行大量的插入/删除的操作,这样作的好处就体现不出来。
应该使用online的mirroring功能吗?
Question:应该使用online的mirroring功能吗?
informix6.0以上的版本开始支持镜像(mirroring),镜像可以将相同的数据复制到多个磁盘上,当一个磁盘坏掉,online可以继续使用镜像磁盘来代替坏掉的磁盘。
一些操作系统(如HP-UX)也提供镜像的功能,还有硬件方式的镜像,三种镜像方式哪一种更好呢?
通常硬件镜像更好。因为它最快,然后是操作系统的镜像,最后才是ONLINE镜像。ONLINE镜像需要作一些逻辑上的运算,用于判断如何处理down掉的chunk。而是使用HP-UX或者硬件上的镜像不会出现这种情况。
HP的逻辑卷管理可以让你以“stripe"的方式将extents以轮转的方式分别存储在多个磁盘上。如果你使用数据分片策略,这也许会/也许不会带来性能的提高。
如果你使用HP-UX的磁盘镜像,在主磁盘繁忙的时候,读盘操作会被转移到镜像盘上,在磁盘负载很重的情况下,这会带来很大的性能提高。
关于NFS?
1.我们可以在远程主机上运行应用程序吗?(如C程序,shell scripts,perl scripts等等)运行的性能和在本地运行同样的程序相比如何?
由于NFS mounts远程主机上的文件系统到你的本地计算机,你可以象存取本地磁盘一样存取远程文件系统。这对性能的影响不大。
2.运行NFS需要什么软件?
只需要NFS和TCP/IP。
3.管理NFS是否困难?
主要的困难来自你必须要维护你的分布式文件的UID和GID必须要同步。使用NIS会使这项工作变得容易一点。
如何使用cron自动进行数据库备份?
echo '\n0' | tbtape -s 1 | head -100
如何知道一个表存在在哪些dbspace上?
以下是一些sql语句:
SELECT TRUNC(partnum/16777216) dbspace, COUNT(*) tables,
SUM(nrows) tot_rows, SUM(nrows*rowsize) bytes FROM systables
WHERE tabtype = 'T' GROUP BY 1 ORDER BY 1;
如果你在你的数据库中创建一个叫做'dbspaces'的表,然后将onstat -D的输出的dbspace名称放入这个表中,然后你就可以用:
SELECT dbs_name[1,12] dbspace,
COUNT(*) tables, SUM(nrows) tot_rows,
SUM(nrows*rowsize) bytes
FROM systables, dbspaces
WHERE tabtype = 'T'
AND dbs_no = trunc(partnum/16777216)
GROUP BY 1 ORDER BY 1;
输出为:
dbspace tables tot_rows bytes
mcs_aaaaa 28 51 3715
mcs_catalog 22 2695 114810
mcs_eeeee 25 224 45446
mcs_fffff 32 1412 201445
mcs_mmmmm 35 165 262599
mcs_wwwww 28 449 79385
注意:(“byte"仅仅为数据的字节数,不包括索引和其他的开销)
怎样使用“informix”用户和"informix"组?
1.是否应该使用informix帐号来管理数据库,例如:grant/revoke权限,创建/删除表,dbload等等。
2.应该创建一个单独的帐号来作这些事情吗?为什么? 3.是否应该用informix帐号来管理数据库应用程序,并且将所有的用户置于这个组内,?
我们仅仅使用informix帐号来进行DBA的管理工作,而不是用它来做所有的事情,你应该有一个informix帐号和一个informix组,帐号和组都是唯一的。在informix组中只应该有informix一个用户。
我们有一个“应用”帐号,这个帐号是所有的非系统表的属主,并且用它设置所有的权限,拥有所有的资源,数据,和可执行目录和代码。这样做的目的是隔离数据管理和服务器管理两种不同的工作。DBA的功能是独立的,(并且只有一个人可以执行这个工作),如果你的数据库规模很大或者即将变得很大,你会体会到这样作的好处。 如果你脱离这个原则,会出现严重的安全隐患。informix组内的其他用户可以执行INFORMIXDIR目录下的很多应用程序,而这些应用程序你一定不希望由他去执行。所以没有必要去冒险将所有的用户放在informix组中。
如何知道数据库应用使用CPU的时间
通常在UNIX下面,可以使用time命令来得出一个进程说所占用的CPU的时间:
$ /bin/time test.4ge
real 9.0
user 1.6
sys .14
在这里,1.6+1.4 就是程序test.4ge所消耗的所有的CPU的时间。而“real”在这里不是特别重要。
然而在informix的环境中,time命令忽略了一个重要的方面,sqlturbo(数据库引擎)所使用的CPU时间。而且,如果你在一个应用程序中使用一个RUN语句,还要增加命令被RUN语句触发的时间。
一些操作系统(SCO Unix, Unix SVR4) 有一个叫做'timex"的命令,使用这个命令可以获得进程和其子进程所使用的CPU时间,在使用timex命令之前必须先打开记帐功能。
要打开记帐功能,首先用root用户登录系统,然后运行:
OS COMMAND
-------- -------------------------------------
SCO Unix $ /usr/lib/acct/accton /usr/adm/pacct
Unix SVR4 $ /usr/lib/acct/accton /var/adm/pacct
Others OS $ man acct
当记帐功能打开之后,你就可以执行timex命令。使用-p选项(可以获得子进程使用的CPU时间)。
$ timex -p fglgo test.4gi
********
COMMAND RT END REAL * CPU * CHARS BLOCKS
NAME USER TTYNAME TIME TIME (SECS) *(SECS)*TRNSFD R/W
fglgo ignacio ttyp0 17:35:05 17:35:05 0.59 * 3.02 * 26256 9
#sqlturbo ignacio ttyp0 17:35:05 17:35:05 0.56 * 4.26 * 32248 12
********
‘timex'输出了两条记录,一条是应用程序本身,一条是sqlturbo所占用的CPU时间。如果在应用中使用了RUN语句,'timex'中还会有第三条记录包括run语句触发命令的时间。
为了获得整个CPU的使用时间,你必须将各个CPU字段中的时间加起来。
Total_CPU_time = fglgo_time + sqlturbo_time = 3.02 secs + 4.26 secs ==> Total_CPU_time = 7.28 secs
通常在想比较程序的两个不同版本的执行时间的时候可以使用timex。如果你要使用4GL程序(可能使用一条insert语句,或者提交一些存储过程),'timex'会告诉你哪个版本更好。而,当你可以根据CHARS TRNSFD字段来判断应用程序和sqlturbo之间 数据交换的频繁程度。
使用ISQL/DBACCESS来进行SELECT语句优化需要注意哪些事项?
当你使用ISQL/DBACCESS等工具来进行select语句的设计和优化的时候,请确认在你运行这个select语句的时候,将select 语句的输出定向到/dev/null文件中去。因为如果将ISQL/DBACCESS的输出到屏幕的时候,一次只输出一屏的数据,因此会造成时间上的延续。
如何知道一个database存储在哪个dbspace上面?
申明:如果使用create table ... in dbspace....语句,即使用数据分片,下面的的方法也许不会有用,但是大多少情况下都是可以用的:
对sysmaster表使用以下的语句:
select b.dbsname, a.name
from sysdbspaces a, systabnames b
where a.dbsnum= partdbsnum(b.partnum)
and b.tabname="systables" and b.dbsname="yourdbname"
在7.x以上的版本,可以用: SELECT DBINFO("DBSPACE", HEX(partnum))
FROM systables WHERE tabname = "systables"
On 5.x instances, try: SELECT HEX(partnum)
FROM systables WHERE tabname = "systables"
在输出的最开始的两个字符(在0x的后面)可以看到chunk号, 通过这个chunk号,可以用onstat -d来获得dbspaces的名称。
如何找出数据库中使用的磁盘I/O最多的哪些线索?
在sysmaster数据库中运行以下的sql语句:
SELECT p.sid, username, tty, seqscans, dsksorts,
total_sorts from syssesprof p, syssessions s
WHERE p.sid = s.sid;
装载数据的时候如何清除掉重复的记录?
假设使用的是informix 7.22版本:执行如下的语句:
SET INDEXES idx_name DISABLED;
START VIOLATIONS TABLE FOR tab_name;
SET INDEXES idx_name ENABLED even better,
SET INDEXES idx_name FILTERING WITHOUT ERROR
然后装载数据
所有的重复的数据都将被放到violation和diagnositc表中,然后你就可以通过在violation表中调试哪些错误的记录,然后再将它们插入到主表中去。
为什么使用High Performance Loader装载数据的时候没有错误信息? 检查violation表,如果你没有特意对其命名的话,这些表的名称都是table_vio
和table_dia。在vio表中是出错记录,在dia表中是产生这些错误的原因。你可以使用tuple_id字段将两个表连接起来,并在HPL手册中查找出错的原因。
如何使用SMI表来查找一个表所占用的磁盘空间的大小?
执行以下sql语句:
select s.name dbspace, n.dbsname database,
sum(ti_nptotal) total, sum(ti_npused) used,
sum(ti_npdata) data, sum(ti_npused) - sum(ti_npdata) idx
from systabinfo i,systabnames n, sysdbspaces s
where i.ti_partnum = n.partnum and partdbsnum(i.ti_partnum)=s.dbsnum
group by 1,2
order by 1,2
如何在UNIX上存取NT上面的数据库?
UNIX系统之间可以通过设置.rhosts和hosts,equiv文件来实现UNIX系统之间存储数据库,而在NT下面将hosts.equiv文件放在c:\winnt\system32\drivers\etc下面即可。
如何判断数据库性能变差是由于网络的原因?
很多性能的问题是由于网络引起的,包括网络硬件故障和网络设置的问题。要确认是否存在网络方面的问题,可以在服务器上执行以下几个命令:
arp -a
netstat -r
如果这执行这两个命令后的输出不正常,就可以判定网络存在问题。当arp -a 命令的输出发生暂停,并且显示一个IP地址,你就可以找到故障发生的节点(这并不能说明这个节点本身有问题)。当netstat -r的输出发生暂停,可能存在路由方面的问题,如果需要,可以用“snoop”命令来进行进一步的检查,直到找到问题的根源。
如何启动KAIO(异步IO)
KAIO (Kernel Asyncronous I/O) 是informix7.x的一个特征,大多数的平台都支持这种特征,
假设:
1)你的平台支持这个功能(检查$INFORMIXDIR/release版本中的内容看看是否你的平台支持KAIO)
2)你使用的是裸分区
以下是一些UNIX系统启动KAIO的步骤:
HP-UX:
1.关闭online
2.安装特殊的设备驱动程序
进入SAM kernel cfg; drivers; select asyncdsk; actions; add driver to kernel; create a new kernel; move kernel into place and continue shutdown [reboot] now...
3.创建特殊的异步设备文件
mknod /dev/async c 101 1
4.临时设置KAIO环境变量。这个变量需要在启动脚本中进行设置:
export KAIOON=1
5.启动online
6.检查KAIO线索
使用命令onstat -g ath
AIX 4.1.5
/usr/sbin/mkdev -l aio0
你必须在每次系统启动的时候作这些工作,或者将其放在/etc/inittab文件中:
kaio:2:wait:/usr/sbin/mkdev -l aio0
如何使用onbar对一个dbspace进行在线的热恢复
export ARCHIVE_TEST=true
使用onstat -d 来选择一个你想要将其标记为down的chunk,并且找到其对应的dbspace名
onmode -o 'chunk number'; - 对每个被标记为down状态的chunk执行这个操作
onmode -O :让down掉的dbspaces不会堵塞checkpoints的发生,-回答‘YES’会将发生I/O错误的 dbspaces变为不可用状态,并且要求从归档数据中恢复这个dbspace。
onbar -r 'dbspace name'
哪些查询只能使用单线索(不能并行化)?
查询中不包含任何“并行”操作(扫描,连接,集合,分组)。 查询使用CURSOR STABILITY ISOLATION LEVEL优化。 查询使用光标,如cursor FOR UPDATE or WITH HOLD 查询中包含有SPL调用。
如何加速排序和创建索引的速度?
对于大的排序操作象创建索引和更新统计信息,将环境变量PSORT_DBTEMP 尽可能的设置为较大的值(最少为3,记住这个最小值可能会限制排序数据的大小)。同时,,设置PSORT_NPROCS 为一个20到40之间的一个值也会加快排序的速度,只要你可以为一个任务分配足够多的资源。这样作可能会为你节约15或者20分钟的排序时间。
可以将ontape输出到一个磁盘的文件中吗?
informix"支持"将ontape输出到一个文件中。
然而,因为ontape默认是输出到磁带设备上,并且所有的动作都是以此为基础的。你有“责任”做所有的这些事情来满足程序的需求。(如模拟一个压缩操作,当磁带满的时候换带。处理倒带操作,逻辑日志的输出和溢出等等)你可以在互联网上的informix 用户组站点()上找到一些shell 脚本可以用来来模拟以上的功能。
输出文件的大小的能够到达多大而不会出错,这个大小高度依赖操作系统和ontape的版本。在Informix Dynamic Server versions 7.2以前的版本,ontape支持的文件不能超过2GB。在7.2以上的版本中,这个限制来自操作系统,一般还是2GB,编写写一个程序,当磁盘文件的大小快要到达2GB的时候就交换到另外一个文件,让ontape认为是正在换带,这并不是特别难。当然,挑战来自为这些文件作标记,并且让它们在ontape进行数据恢复的时候能够以正确的顺序来读取这些文件。
如果是“关键”的系统,你必须要“彻底”测试归档和恢复功能是否能够正常进行。并且保存好磁盘的规划信息,详细做好文档记录,让除你之外的其它人根据这些文档就可以处理灾难发生时候的数据恢复。 | | |