JAVA学习之路

常用链接

统计

最新评论

Informix培训教材整理之FAQ

转自:http://unix-cd.com/unixcd12/article_5444.html

为什么在一个有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功能吗?

      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用户组站点(http://www.iiug.org)上找到一些shell 脚本可以用来来模拟以上的功能。

      输出文件的大小的能够到达多大而不会出错,这个大小高度依赖操作系统和ontape的版本。在Informix Dynamic Server versions 7.2以前的版本,ontape支持的文件不能超过2GB。在7.2以上的版本中,这个限制来自操作系统,一般还是2GB,编写写一个程序,当磁盘文件的大小快要到达2GB的时候就交换到另外一个文件,让ontape认为是正在换带,这并不是特别难。当然,挑战来自为这些文件作标记,并且让它们在ontape进行数据恢复的时候能够以正确的顺序来读取这些文件。

      如果是“关键”的系统,你必须要“彻底”测试归档和恢复功能是否能够正常进行。并且保存好磁盘的规划信息,详细做好文档记录,让除你之外的其它人根据这些文档就可以处理灾难发生时候的数据恢复。

 

 

一四 INFORMIX-OnLine故障诊断与排除

 

1)系统不能进入静态方式

      开放系统以其无与伦比的能力连接不同的计算机软件,硬件。在这种环境下,诊断问题时就需要关注问题的全局与细节。本文就如果诊断INFORMIX-Online的问题给出了良好的建议。

      诊断问题的症状

      系统管理员诊断问题时首先要定义问题的症状。      

        系统是否难于进入静态(quiescent)状态?            

        是否有非正常结束的INFORMIX系统进程?            

        系统进程是否定期挂起?      

      下面的讨论指出如何定位系统问题,讨论可能的起因,并对这些问题的解决提出建议。       

      系统不能进入静态方式

         该症状常常伴有一条错误信息。一般错误是:

      tbinit:fatal error in shared memory creation (共享内存生成时有严重错误)

      检查系统初始化时定义的系统日志文件来发现错误的出处。该日志的缺省名为$INFORMIXDIR/online.log。在此文件中会看到与下面相近的信息:

      16:00:56 Cannot Open Primary Chunk '/dev/turbo_root',errno = 13

        16:00:56 Cannot Open Primary Chunk '/dev/turbo_root',errno = 13

        16:00:56 I/O error,Primary Chunk 'dev/turbo_root' -- Offline

        16:00:56 I/O lseek() chunk 1,pagenum 0, pagecnt 1 -->errno =9

        16:00:56 INFORMIX-Online Stopped

      这些错误是由UNIX权限问题造成的。OnLine产品需要由root来安装。系统的部分可执行程序应属于root或者root有权限。所有INFORMIX系统文件的属主及权限都应该记录在$INFORMIXDIR/etc/onlinefiles中。检查所有OnLine文件权限,属主,属组是否正确。

      也应检查chunk的权限,保证CHUNK有UNIX权限660(crw-rw----),其属主,属组为informix,建议管理员使用系统管理员实用程序tbmonitor定义OnLine系统配置。初始化例程自动进行权限检查,计算可利用的磁盘空间,但如果配置文件是直接修改的,就并非如此了。

      如果系统日志文件中并未记录有用的错误信息,而OnLine系统刚刚升级,则应检查确认页大小(与OnLine产品一道发送的缺省配置文件中定义)是否已经改变。若页大小变化了,就必须从老系统输出的数据(dbexport)再将数据输入到新系统上去(用dbimport)。       

      错误tbinit:fatal error in shared memory creation 经常伴有操作系统错误或者附加的OnLine错误。这也能用来判定问题为什么会发生。下列错误说明为何共享内存不能生成。      

        tbinit:shmget[EEXIT][17]:            

         tbinit:shmget[EINVAL][22]:   

        tbinit shmat[EINVAL][22]:                  

        tbinit shmget[ENOSPC][28]:

        Bad Primary Chunk '/dev/devname'                  

        tbinit:shmget[EEXIST][17]:             

      tbinit:shmget[EEXIT][17]:

      这个错误表明共享内存段在申请的内存位置上已经存在。tbinit进程从环境变量TBCONFIG指定的文件读取配置。若TBCONFIG未指定,tbinit从$INFORMIXDIR/etc/tbconfig文件读取配置。一旦获取配置信息,tbinit派生一个子进程,它将成为tbinit后台进程。tbinit后台进程用唯一的SERVERNUM值做一部分输入值来计算共享内存键值,唯一的SERVERNUM值确保每个OnLine系统生成自己特定的共享内存空间。仔细检查以保证文件配置正确,SERVERNUM的值唯一。       

      tbinit:shmget [EINVAL][22]:or tbinit:shmat[EINVAL][22]

      当无效参数传递给UNIX调用时,UNIX产生错误。用OnLine术语来说这意味着tbinit申请的共享内存未被分配。一旦UNIX接受SERVERNUM和共享内存键值,tbinit便可将Online共享内存段附加在它的虚拟地址空间上。虚拟地址,共享内存段要附加的tbinit(或其他的用户进程)的内存空间是由SHMBASE定义的。若SHMBASE的值不合法,或申请共享内存大于共享内存核心参数允许的值时,或共享内存段由于边界对齐问题而无法连续分配时,UNIX会认为传给共享内存附加调用的内存值是无效的。

      现在对UNIX核心参数作一回顾,以下描述的时有关共享内存配置的参数。      

      核心参数

      SHMSIZE 是操作系统范围内共享内存段的最大值(以k为单位)。

      SHMMAX 是操作系统范围内共享内存段的最大值(以字节为单位)。

      SHMMIN 是操作系统范围内共享内存段的最小值(以字节为单位)。

      SHMMNI 是操作系统范围内共享内存标识的最小数值。

      SHMLBA 是共享内存低段地址,也就是附加共享内存的边界地址

      SHMSEG 是每个进程附加共享内存段的最大数目。

      SHMALL 时系统范围内共享内存的最大量。

      信号灯分配参数

      SEMMNI 是操作系统范围内信号灯标识的最大值

      SEMMNS 是操作系统范围内信号灯的最大值

      SEMMSL 是每个标识信号灯的最大值。       

      参数值的定义

      SHMALL*操作系统页大小=全部可能的共享内存(以字节为单位)。

      SHMMAX=SHMSIZE*1024.

      SHMMNI*SHMMAX=操作系统范围内可编址的共享内存(以字节为单位)。

      SHMSEG*SHMMAX=一个操作系统进程可编址的共享内存(以字节为单位)。      

      参数设置指导:

      规则1 SHMALL * 页大小 >= SHMSEG * SHMMAX

      规则2 SHMALL * 页大小 = SHMNI * SHMMAX

      规则3 SHMMSL = 主机用户进程数/25

      规则4 SHMMAX > SHMLBA

      tbinit: shmget[ENOSPC][28]:

      当系统申请空间,而设备已满时,UNIX产生该错误。UNIX申请共享内存的交换区,保证交换空间驻留的设备上有足够的空间。没有足够的共享内存ID时也会发生错误,检查系统SHMMNI核心参数。       

      Bad Primary Chunk '/dev/devname'

      由于控制器,硬件或者权限问题,使得向chunk写失败时,Online标记该chunk为down,这样做的目的是为了通知管理员数据完整性已经被破坏,检查系统日志文件中I/O错误。以下是典型的硬件I/O错误的例子:

      I/O error,Primary Chunk '/dev/rdsk/devname' -- Offline

      I/O read(),Chunk 2,pagenum 272714,pagecnt 1 -->errno =5

      I/O write() chunk 2,pagenum 2,pagecnt 1 --> errno = 5

      发生I/O错误时,检查控制器和硬件。许多UNIX系统提供检查未安装原始设备的低级别实用程序,不要在未安装的原始设备上使用fsck命令,这是因为fsck会覆盖设备上存储的信息,为恢复系统,INFORMIX建议管理员恢复最后的存档,用日志恢复失败了的写操作。

      一旦共享内存初始化完成,物理日志从上一次检查点开始检查物理日志的前象,如果该记录存在,开始FAST RECOVERY,进入物理恢复,每个前映象写回到磁盘上正确的位置上,一旦完成后,逻辑恢复开始,并处理上次检查点之后逻辑日志中记录所对应的事务,如果快速恢复非正常结束,或是不能让OnLine进入静态(Quiescent)方式,则让OnLine进入脱机(off-line)方式,再启动OnLine。若OnLiner仍不能进入静态方式,则应该恢复系统存档。 

2)  OnLine非正常结束

            OnLine非正常结束时,描述有关OnLine进入脱机方式原因的信息将写入日志,下面时OnLine结束时系统日志中登陆日志的示例:      

      Process Aborted Abnormally: pid=22500 user=210 us=c003f15c flags=a01      

      Process Aborted Abnormally (critial section):pid=22500 user=210 flag=a01

      INFORMIX-OnLine entering ABORT mode!!! INFORMIX-OnLine Stopped       

      日志条目显示一个进入临界状态的sqlturbo进程非正常结束,临界状态是指一个进程执行写调用而不能被中断所用的术语。如果一个进程处于临界状态时非正常结束,OnLine为保护数据完整性而进入脱机方式。当OnLine重新启动时会执行快速恢复,回滚所有未完成的事务。

      如果持有锁存器(latch)的进程非正常结束,OnLine也会非正常结束。锁存器用于控制对诸如缓冲区,锁定表等共享内存资源的访问。为防止干涉其它进程申请共享内存资源,INFORMIX OnLine控制对有锁存器的资源表的访问。

      虽然OnLine后台进程对夭折的进程进行日常的清理工作,但数据一致性阻止后台进程在清除过程中释放共享内存锁存器。对后台进程来说,判断用户进程是否完成对数据库的修改是不可能的。为解脱这以一困境,OnLine强制自己进入脱机方式。当OnLine回到联机(Online)方式时,自动进行快速恢复。快速恢复使OnLine达到与最后一个完成事务一致的状态。

      当持有锁存器的进程结束时,会生成以下的条目:

      Process Aborted Abnormally: pid=10743 user=104 us=60204c flags=21

      Process Aborted Abnormally (latch): pid=10743 user=104 flags=21

      INFORMIX-OnLine entering ABORT MODE!!!

      -- OnLine Aborting -- us=6019a8,pid=11987,uid=1000

      这些日志条目提供的信息在判定进程为何非正常结束时十分有用,条目中各域的定义如下:

      pid---------sqlturbo UNIX进程id

      user--------真正用户id

      us----------共享内存中用户结构的地址

      flags-------定义如下

      0x0000001------0x0000001 正在使用的用户结构

      0x0000002------0x0000002 等待锁存器

      0x0000004------0x0000004 等待锁

      0x0000008------0x0000008 等待缓冲区

      0x0000010------0x0000010 等待检查点

      0x0000020------0x0000020 等待读取调用

      0x0000040------0x0000040 向存档磁道写逻辑日志

      0x0000080 等待清除长事务

      0x0000100------0x0000080 特定turbo检测用户

      0x0000200 处于事务中

      0x0000400 进程在回滚

      0x0000800------0x0000100 处于临界状态的进程继续...

      0x0001000------0x0000200 特定的后台进程

      0x0002000 开始工作日志登记

      0x0004000------0x0000400 存档

      0x0008000------0x0000800 清除死进程

      0x0020000------0x00002000 特定缓冲区刷新进程

      0x0010000------0x0002000 等待逻辑缓冲区写入

      0x0040000------0x0004000 该进程是远程服务器

      0x0080000 该进程正完成远程任务

      0x0100000------0x0008000死锁超时

      -----------0x00010000-----普通锁超时

      -----------0x00020000-----超时等待期已结束

      -----------0x00040000-----等待事务

         以上的日志条目中,sqlturbo进程的UNIX进程id为10743,真正用户id为104,共享内存中用户结构的地址为0x60204c,标志显示用户结构正在使用中,OnLine引擎正处于读取调用之中(0x00000001,&0x00000020)。

      这个信息可以标识非正常结束的用户,查明他或她是否遇到意外的错误,或以某种方式导致进程的非正常结束。用户不应对Informix进程使用kill -9命令。管理员可以用onmode -z pid命令中止某一个sqlturbo线索。如果进程正持有锁存器或处于临界状态,tbmode命令不会立即中止该进程。

3) OnLine进程似乎被挂起

         当OnLine用户抱怨他们的进程被挂起,或者不能与OnLine相互作用时,运行onstat -a ,获得有关问题的本质信息。onstat是OnLine提供的实用程序,是用来监视系统的命令。它提供了与tb_Monitor(onmonitor)实用程序相近的,但更为详尽的统计数字。

      OnLine挂起的最明显的原因时逻辑日志已充满而且需要备份。在tbstat输出中检查逻辑日志的状态。在逻辑日志填满后备份日志,就会让OnLine继续处理事务。

      进程必须等待检查点完成。检查点请求可以阻止进程进入临界状态或者获得锁存器资源。onstat显示的第1行为状态行,它会显示是否申请了检查点。如果条件成立,有可能是检查点在等待资源。检查用户结构下的等待队列来找出资源的地址。一旦定位到资源,判定拥有该资源的用户进程状态。已经进入临界状态,或是持有锁存器资源的进程可以阻止检查点的完成。例如,存档进程在磁带改换期间一直持有一个锁存器,并禁止检查点的发生。      

      帮助诊断问题的实用程序    

          实用程序名

          目的

          描述

          使用        

          dbexport

          卸成ascii文件

          把数据库卸到磁盘或磁带上,生成包含表结构的数据库.sql文件。结构并不包含extent大小

          数据库移植到其它平台                

          dbimport

          加载ascii文件

          从dbexport生成的数据库结构及ascii数据,生成并加载数据库,直接由磁盘或磁带加载。

          由其它平台输入数据 

          tbunload

          卸成二进制文件

          将数据库或表的数据影象,卸到磁盘或磁带上,用于页大小,机器结构相同的OnLine系统

          高效的,真正二进制方式卸数据 

          tbload

          由二进制文件加载

          由tbunload生成的磁带加载数据库或表

          高效的,数据库数据加载方式 

          tbinit

          管理

          初始化共享内存,启动共享内存后台进程

          tbmonitor命令行 

          tbmode

          管理

          使OnLine脱机或联机,中止OnLine进程

          tbmonitor命令行 

          tbmonitor

          管理

          由管理员来开启OnLine系统,报告OnLine系统状态,执行存档,恢复备份逻辑日志,改变系统状态

          交互式全功能管理程序 

          tbparams

          管理

          由管理员用来增加或删除逻辑日志,改变物理日志的大小及位置

          tbmonitor命令行 

          tbspaces

          管理

          由管理员用来增加或删除dbspace或blobspace,为它们增加chunk,改变状态

          tbmonitor命令行                 

          tbstat

          系统检测员

          提供有关OnLine状态,共享内存资源的详细信息

          报告/debug工具                 

          tbtape

          管理

          在磁带上作系统存档,或备份逻辑日志

          tbmonitor命令行                 

          tblog

          系统检测员

          提供有关逻辑日志条目的详细信息

          报告/debug工具                 

          tbcheck

          系统检测员

          报告并检查OnLine系统完整性,执行数据,索引页,extent,位图页的低级别检测,提供有关保留页,extent和系统信息

          报告/debug工具

     

 

一五 监视Informix-Online动态服务器

                                         

        onstat 和oncheck实用工具                        

        onperf实用工具         

      什么是信息日志       

      online信息日志是一个操作系统的文件。在Online信息日志中包括的信息通常不需要立刻进行处理。通过设置ONCONFIG文件中MSGPATH的值,你可以指定信息日志的路径名。为了得到OnLine信息日志的名字和20条最新的记录,应执行onstat -m命令。

      利用ON-Monitor监视

      ON-Monitor提供了一个全面监视Online的简单方法。大多数监视功能在Status菜单下都是可用的。       

      利用SMI表监视

      系统监视界面(SMI)表是OnLine管理的专用表。它包含了有关数据库服务器状态的动态信息。你可以对它们使用SELECT语句来决定你想要了解有关数据库服务器的几乎任何事情。      

      利用onstat和oncheck实用工具监视

      onstat 和oncheck提供了一种从命令行监视OnLine信息的方法。       

      onstat 与oncheck的比较

      onstat 实用工具从共享内存读数据并报告在命令执行期间内的精确统计结果。也就是说,onstat描述在处理期间动态改变的信息,如缓冲区,锁和用户的情况。

      oncheck实用工具主要倾向于显示配置和磁盘的使用信息,这些信息驻留在磁盘上,而且变化较少。       

      使用onperf监视

      onLine包括称为onperf图形监视工具。这个工具能够 

        监视onstat提供的大多数信息。

      下面介绍使用命令行实用工具onstat

      onstat -c oncheck -pr     检查配置信息

     onstat -m;onstat -p       检查检查点信息      

      onstat -g seg            监视共享内存段       

      onstat -p:                 可获得有关被高速缓冲的读写的统计信息。包括:                    

                      从共享内存缓冲区读的数目(bufreads),

                      从高速缓存读的百分比(%cached)

                      写共享内存的数目(bufwrits)

                      向高速缓存写的百分比(%cached)                      

      onstat -B:         可获得下面的缓冲区信息:         

                      每个普通共享内存缓冲区的地址

                      当前共享内存中的所有内存页的页号

                      当前占有缓冲区的线程的地址

                      等待各缓冲区的第一个线程的地址        

      onstat -b:        可获得下面各个缓冲区上的信息:         

                      当前占用各缓冲区的线索的地址

                      缓冲区中页的页号

                      缓冲区中页的类型

                      缓冲区设置锁定的类型

                      当前占用缓冲区的线程的地址

                      等待各缓冲区的第一个线程的地址

      你可以把用户线程的地址与在onstat -u显示中出现的地址进行比较,以获得会话id号。

      onstat -k:         显示有关活动的锁定信息。 

                      产生锁定的用户线索

                      锁的类型

                      锁的范围

         onstat -g glo    显示有关当前正在运行的各个虚处理机信息,以及各虚处理机类的累加信息(从系统启动开始)。

      onstat -u       显示有关所有需要RSAM任务控制块结构的活动线程的信息。活动线程包括属于用户会话的线程,和一些相应的服务器daemons线索.还包括如下信息:      

        各个线程的地址

        标志出线索的当前状态

        有关线程属于会话的会话id和用户登录id.为0的会话id表示daemon线程。

        线程是否在等待特定的资源和该资源的地址

        线程占用的锁的数目

        线程已执行的读调用数和写调用数

        自最近一次的OnLine初始化以来,分配出去的并发用户线索的最大数目

      onstat -g ses       

      可以监视分配一个线索的资源。

      onstat -x:

      显示关于每个打开事务的下列信息:        

        事务在共享内存中的地址

        事务的当前状态

        事务处于什么阶段

        事务的特征

        拥有事务的线程

        事务占用锁定的数量

        记录begin work记录的逻辑日志文件

        隔离级

        试图开始恢复线程的数目

        事务协调者

        从你最近一次初始化OnLine到现在的并发事务的最大数      

      onstat -g sql       

      获得有关各个线索执行最后的sql语句的摘要信息。

      onstat -l       

      显示物理日志信息,逻辑日志信息和单个的逻辑日志文件上的信息,包括:      

        逻辑日志文件描述符的地址

        逻辑日志文件的Logid号

        指示各个日志状态的状态标记.

        日志文件的唯一id

        文件的起始页

        文件大小(以页为单位),已使用的页面数,以及已使用的页面所占的比率

      onstat -d       

      列出所有的dbspaces和blobspaces,以及在这些空间中的所有大块和相关的信息。      

        可提供的大块信息有:

        大块地址

        大块号和相关联的dbspace号

        在设备中的偏移量(单位是页面)

        大块尺寸

        大块内可用页的数量

        可用blobspace大致数量

        物理设备的路径名                   

      onstat -g iof       

      显示从个大块中读的数量和写入各大块的数量.如果一大块具有相对很大数量的I/O活动,

      这一大块可能正成为系统瓶颈。此选项有助于监视对于经过分片的表的不同分段的I/O需求的分布是否均衡。

      Oncheck -pe       

      可得到大块信息的物理布局

       Dbspace 名,所有者,以及dbspace的建立日期 

      大块的页大小(以页为单位),使用的页数量和可用页的数量

      大块内的所有表以及它们的初始页号,以页数为单位的表长度的列表

      oncheck -pt       

      可执行带有数据库名和表名参数的oncheck -pt命令来获得下列数据库或表中各个tblspace的信息范围数量

      第一个范围的大小

      下一个范围的大小

      分配的页数

      使用的页数

      oncheck -pB       

      可执行带有作为参数的数据库名或表名的oncheck -pB命令。

      在所有的blobspaces中该表或数据库使用blob页的数量

      该表或数据库中的各个blob,blobpage的满程度

      监视数据复制状态       

      可监视OnLine数据库服务器的数据复制状态,来确定下列信息:      

        数据库服务器类型(主要的,从属的,或标准的)

        其它配对数据库服务器的名字

        数据复制是否在运行

        数据复制参数的值      

      onstat -g dri       

      可得到整个数据复制的监视信息。            

        数据库服务器类型

        数据复制状态(开,或关)

        配对的数据库服务器

        最新的数据复制检查点

        数据复制配置参数值  

 

 

附录:

    主要SQL语句详解

CREATE DATABASE database_name [WITH LOG IN “pathname”]

 

创建数据库。

database_name:数据库名称。

 “pathname”:事务处理日志文件。

 创建一database_name.dbs目录,存取权限由GRANT设定,无日志文件就不能使用

 BEGIN WORK等事务语句(可用START DATABASE语句来改变)。

 可选定当前数据库的日志文件。

如:select dirpath form systables where tabtype = “L”;

 例:create databse customerdb with log in “/usr/john/log/customer.log”;

 DATABASE databse-name [EXCLUSIVE] 

选择数据库。

database_name:数据库名称。

 EXCLUSIVE:独占状态。

 存取当前目录和DBPATH中指定的目录下的数据库,事务中处理过程中不要使用此语句。

 例:dtabase customerdb;

 CLOSE DATABASE 

关闭当前数据库。

database_name:数据库名称。

 此语句之后,只有下列语句合法:

CREATE DATABASE; DATABASE; DROP DATABSE; ROLLFORWARD DATABASE;

 删除数据库前必须使用此语句。

例:close database;

 DROP DATABASE database_name 

删除指定数据库。

database_name:数据库名称。

 用户是DBA或所有表的拥有者;删除所有文件,但不包括数据库目录;不允许删除当前数据库(须先关闭当前数据库);事务中处理过程中不能使用此语句,通过ROLLBACK WORK 也不可将数据库恢复。

 例:drop databse customerdb;

CREATE [TEMP] TABLE table-name (column_name datatype [NOT NULL], …) 

 [IN “pathname”]

 创建表或临时表。

table-name :表名称。

 column_name:字段名称。

 data-type:字段数据类型。

 path-name:指定表的存放位置

 TEMP用于指定建立临时表;表名要唯一,字段要唯一;有CONNECT权限的用户可建立临时表;创建的表缺省允许CONNECT用户存取,但不可以ALTER。

 例:create table user

 ( c0 serial not null, c1 char (10),

  c2 char(2),

  c3 smallint,

  c4 decimal(6,3),

  c5 date

 ) in “usr/john/customer.dbs/user;

ALTER TABLE 

ALTER TABLE table-name 

 {ADD (newcol_name newcol_type [BEFORE oldcol_name], …) | DROP (oldcol_name, …)

 | MODIFY (oldcol_name newcol_type [NOT NULL], … )}, …

 修改表结构。

table-name:表名称。

 newcol_name:新字段名称

 newcol_type:新字段类型

 oldcol_name:老字段名称

 可以使用单个或多个ADD子句、DROP子句、MODIFY子句,但某个字句失败,操作即中止;原字段是NULL,不允许MODIFY为NOT NULL,除非所有NULL字段中均非空,反之可以;ALTER使用者是表的拥有者或拥有DBA权限,或被授权;事务中处理过程中不要使用此语句。

 例:alter table user

 add ( c6 char(20) before c5);  

RENAME TABLE oldname TO newname 

修改表名。

oldname:原名称。

 newname:新名称。

 RENAME使用者是表的拥有者或拥有DBA权限,或被授权;事务中处理过程中不要使用此语句。

 例:rename user to bbb;

DROP TABLE table-name 

删除表。

table-name:表名称。

 删除表意味着删除其中所有数据、各字段上的索引及对表的赋权、视图等;用户不能删除任何系统目录表;语句使用者是表拥有者或拥有DBA权限,事务中处理过程中不要使用此语句。

RENAME COLUMN table.oldcolumn, TO newcolumn 

修改字段名。

table.oldcolumn:表名及原字段名称

 newcolumn:新字段名称。

 语句使用者是表的拥有者或拥有DBA权限或有ALTER权限的用户,事务中处理过程中不要使用此语句。

 例:rename column user.c6 to c7;

CREATE VIEW view-name column-list 

CREATE VIEW view-name column-list AS select_statement [WITH CHECK OPTION]

 创建视图。

view-name:视图名称。

 column-list:字段列表。

 select_statement:SELECT语句。

 以下语句不使用视图:ALTER TABLE,DROP INDEX,ALTER INDEX,LOCK TABLE,CREATE INDEX, RENAME TABLE;视图将延用基表的字段名,对表达式等虚字段和多表间字段重名必须指明标识其字段名;若对视图中某些字段命名,则所有字段都必须命名;视图中数据类型延用基表中的数据类型,虚字段起诀于表达式;不能使用ORDER BY和UNION子句;对视图中所有的字段要有SELECT权限;事务中处理过程中使用此语句,即使事务回滚,视图也将建立,不能恢复。

 例:create view v_user as select * from user where c1 = “B1”;

 DROP VIEW view-name 

删除视图。

view-name:视图名称。

 用户可删除自己建立的视图;视图的后代视图也被删除;事务中处理中不要使用此语句。

例:drop view v_user;

CREATE INDEX  

CREATE [UNIQUE/DISTINCT] [CLUSTER] INDEX index_name ON table_name

 ([column_name ASC/DESC],…) 

 创建索引。

index_name:索引名称。

 table_name:表名称。

 column_name:字段名称。

 UNIQUE/DISTINCT:唯一索引。

 CLUSTER:使表的物理存放顺序按索引排列。

 ASC/DESC:升序或降序,缺省升序。

 语句执行时,将表的状态置为EXCLUSIVE;复合索引最多包含8个字段,所有字段长度和不得大于120字节;事务中处理过程中使用此语句,即使事务回滚,索引将建立,不能恢复。

 例:create cluster index ix_user on user(c5);

ALTER INDEX index-name TO [NOT] CLUSTER 

修改索引性质。

index-name:索引名称。

 TO [NOT] CLUSTER:去掉或加上CLUSTER属性。

 语句执行时,将表的状态置为EXCLUSIVE;事务中处理过程中使用此语句,即使事务回滚,索引性质将改变,不能恢复。

 例:alter index ix_user to not cluster;

DROP INDEX index-name 

删除索引。

index-name:索引名称。

 语句使用者是索引的拥有者或拥有DBA权限,事务中处理过程中不要使用此语句,否则事务无法恢复。

 例:drop index ix_user;

CREATE SYNONYM synonym FOR table-name 

创建同义名。

synonym:同义名

 table-name:表名称

 数据库的创建者可以使用同义名;没有赋予同义名权限的用户不能使用同义名;同义名不能和表名相同;事务中处理过程中不要使用此语句。

例:create synonym user_alias for user;

 DROP SYNONYM synonym

删除同义名。

synonym:同义名

 可以删除自己建立的同义名;事务中处理过程中不要使用此语句,否则无法恢复。

例:drop synonym user_alias;

 UPDATE STATISTICS [FOR TABLE table-name]

 更新数据库的统计数字。

table-name:表名称

 此语句仅作用于当前数据库;可提高查询效率;只有执行此语句,才改变统计数据。

例:update statistics for table user;

    主要SQL语句详解

GRANT {DBA|RESOURCE|CONNECT} TO {PUBLIC|user-list}  授权命令。

 PUBLIC|user-list:全部或指定的用户。

  三种权限居且仅居其一,事务处理过程中不要执行GRANT语句。

  例:grant resource to pulbic;

   GRANT tab-privilege ON table-name TO {PUBLIC|user-list} [WITH GRANT OPTION]  

 授表级权限。

  tab-privilege:表级权限。

  table-name:表名称。

 PUBLIC|user-list:全部或指定的用户。

 [WITH GRANT OPTION]:表示被授权用户有否权限进行二次授权。

  用户可以在自己建立表达式或被[WITH GRANT OPTION]准许的表中进行赋权;限定越多的权限优先级越高。

  例:grant update(c1,c6) on user to dick with grant option;  

 附(INFORMIX的权限)

  (1) 数据库的权限(控制对数据库的访问以及数据库中表的创建和删除)   

 DBA权限:全部权利,修改系统表,建立和删除表与索引、增加和恢复表数据,以及授予其他用户数据库权限等;

 RESOURCE权限:允许对数据库表中的数据进行存取,建立永久性表以及索引。

 CONNECT权限:只允许对数据库表中的数据进行存取,建立和删除视图与临时表。

  (2)表级权限(对表的建立、修改、检索和更新等权限)   

  ALTER:更改权限

 DELETE:删除权限

 INDEX:索引权限

 INSERT:插入权限

 SELECT [(cols)]:指定字段或所有字段上的查询权限,不指明字段缺省为所有字段。

 UPDATE [(cols)] :指定字段或所有字段上的更新权限,不指明字段缺省为所有字段。

 ALL [PRIVILEGES]:以上所有表级权限  

     REVOKE {DBA|RESOURCE|CONNECT} FROM {PUBLIC|user-list} 

 收权命令。

 PUBLIC|user-list:全部或指定的用户。

  三种权限居且仅居其一,事务处理过程中不要执行GRANT语句。

  例:revoke resource from john;

 REVOKE tab-privilege ON table-name FROM {PUBLIC|user-list} 

 收表级权限。

  tab-privilege:表级权限。

  table-name:表名称。

 PUBLIC|user-list:全部或指定的用户。

 [WITH GRANT OPTION]:表示被授权用户有否权限进行二次授权。

  用户只能取消由其本人赋予其他用户的表级存取权限;不能取消自己的权限,对SELECT和UPDATE作取消时,将取消所有表中字段的SELECT 和UPDATE权限。

  例;revoke update on user from dick;

    LOCK TABLE table-name IN {SHARE|EXCLUSIVE} MODE 

 记录级加锁和表级加锁或文件加锁。

  table-name:表名称。

 SHARE:允许读表中数据,但不允许作任何修改

 EXCLUSIVE:禁止其他任何形式访问表

  每次只能对表琐定一次;事务处理过程中,BEGIN WORK后立即执行LOCK TABLE以取代记录级加锁,COMMIT WORK和ROLLBACK WORK语句取消所有对表的加锁;若没有事务处理,锁将保持到用户退出或执行UNLOCK为止。

  例:lock table user in exclusive mode; 

  UNLOCK TABLE table-name 

 取消记录级加锁和表级加锁或文件加锁。

  table-name:表名称。

  例:unlock user;  

  SET LOCK MODE TO [NOT] WAIT 

 改变锁定状态。

 TO [NOT]:等待解锁,有可能被死锁或不等待并提示错误信息,表示此记录被锁,缺省值。

  访问一个EXCLUSIVE状态下的记录,将返回一个错误。 

  START DATABSE db_name [WITH LOG IN “pathname”] 

 启动事务处理。

 “pathname”:事务处理日志文件。

 执行该语句前,需要先关闭当前数据库。

 例;clost database;

  start databse customer with log in “/usr/john/log/customer.log”;

   BEGIN WORK 

 开始事务。例:begin work;  

  COMMIT WORK 

 提交(正常结束)事务。例:commit work;   

  ROLLBACK WORK 

 回滚(非正常结束)事务。例:rollback work;   

  SELECT  

  SELECT select_list FROM tab_name|view_name 

 WHERE condition 

 GROUP BY column_name 

 HAVING condition 

 ORDER BY column_list 

 INTO TEMP table_name

 查询语句。

  select_list:选择表或*

  tab_name:表名称

  view_name:视图名称。

  condition:查询条件,可使用BETWEEN、IN、LIKE、IS NULL、LIKE、MATCHES、NOT、

  AND、OR、=、!=或<>、>、 >= 、<=、<、ALL、ANY、SOME

  column_name:分组字段名称

  condition:群聚条件

  column_list:排序字段列表,缺省ASC,可指定DSC;排序时,NULL值小于非零值。

  table_name:临时表名称

 例:略

 附(常用函数)

 (1)集合函数:

 count(*)、

 sum(数据项/表达式)、avg(数据项/表达式)、max(数据项/表达式)、min(数据项/表达式)

  count(distinct 数据项/表达式)、sum(distinct数据项/表达式)、avg(distinct数据项/表达式)

 (2)代数函数和三角函数

 HEX(数据项/表达式)、ROUND(数据项/表达式)、TRUNC(数据项/表达式)、

 TAN(数据项/表达式)、ABS(数据项/表达式)、MOD(被除数,除数)

 (3)统计函数

  标准差,stdev()、方差,variance()、范围,rang()

 (4)时间函数

 DAY(日期/时间表达式):返回数字型

 MONTH(日期/时间表达式):返回整数

 WEEKDAY(日期/时间表达式):0&#0;&#0;6,0星期天,1星期一;返回整数

 YEAR(日期/时间表达式)、返回整数

 DATE(非日期表达式):返回日期型

 EXTEND(日期/时间表达式,[第一个至最后一个]):返回指定的整数

 MDY(月,日,年):返回日期型

 CURRENT:返回日期型

  (5)时间函数

 ROUND(),四舍五入。如:ROUND(10.95,position)position进行四舍五入的前一位置

 TRUNC(),截取。如:TRUNC(10.95,0)position截取的位置

 INFORMIX临时表在下列情况下自动取消:

 A.退出数据库访问工具(如DBACCESS)

 B.SQL通话结束(DISCONNECT)

 C.发出取消表语句

 D.退出程序时  

  INSERT    INSERT INTO view_name|table_name [(column_list)] valueS (value_list)

  或 INSERT INTO view_name|table_name [(column_list)] select_statement

 插入数据

    view_name|table_name:视图名或表名称

    column_list:数据项列表。

    value_list:值列表

    select_statement:查询语句。

 例:略  

  DELETE FROM view_name|table_name WHERE search-conditions    删除语句。

    view_name|table_name:视图名或表名称

    search-conditions;删除条件

 例:略   

  UPDATE   UPDATE view_name|table_name SET column_1 = value_1ist  WHERE search_conditions

 或UPDATE view_name|table_name SET column_1|* = value_1ist  WHERE search_conditions

 更新数据语句。

    view_name|table_name:表名称或视图表名称

    value_1ist:字段值

    search_conditions:更新数据的条件

 例:略   

  CHECK TABLE table-name  检查索引语句。

 语句使用者是表的拥有者或拥有DBA权限;不能对systable使用此语句。

 例:略   

  REPAIR TABLE table-name  修复索引。

 语句使用者是表的拥有者或拥有DBA权限;不能对systable使用此语句。

 例:略   

  LOAD FROM “file-name” INSERT INTO table_name [(column_name[,…])]  将文本数据栽入表中。

 例:load form “aa.txt” insert into user;   

  UNLOAD TO “pathname”  将表中数据卸为文本。

 例:unload to “aa.txt” select * from user;   

  INFO  系统信息查询。

 INFO TABLES:得到当前数据库上表的名字。

 INFO columns FOR table_name:指定表上的字段信息。

 INFO INDEXES FOR table_name:指定表上的索引信息。

 INFO [ACCESS|PRIVILEGES] FOR table_name:指定表上的存取权限。

 INFO STATUS FOR table_name:指定表的状态信息。  

 

INFORMIX SQL 实践与技巧(1)

      如何加快sql的执行速度?

      1.select 语句中使用sort,或join

      如果你有排序和连接操作,你可以先select数据到一个临时表中,然后再对临时表进行处理。因为临时表是建立在内存中,所以比建立在磁盘上表操作要快的多。

      如:

      SELECT time_records.*, case_name 

      FROM time_records, OUTER cases 

      WHERE time_records.client = "AA1000" 

      AND time_records.case_no = cases.case_no 

      ORDER BY time_records.case_no 

      这个语句返回34个经过排序的记录,花费了5分钟42秒。而:

      SELECT time_records.*, case_name 

      FROM time_records, OUTER cases 

      WHERE time_records.client = "AA1000" 

      AND time_records.case_no = cases.case_no 

      INTO temp foo; 

      SELECT * from foo ORDER BY case_no 

      返回34条记录,只花费了59秒。       

      2.使用not in 或者not exists 语句

      下面的语句看上去没有任何问题,但是可能执行的非常慢:

      SELECT code FROM table1 

      WHERE code NOT IN ( SELECT code FROM table2 ) 

      如果使用下面的方法:

      SELECT code, 0 flag 

      FROM table1 

      INTO TEMP tflag; 

      然后:

      UPDATE tflag SET flag = 1

       WHERE code IN ( SELECT code 

      FROM table2 

      WHERE tflag.code = table2.code ); 

      然后:

      SELECT * FROM 

      tflag 

      WHERE flag = 0; 

      看上去也许要花费更长的时间,但是你会发现不是这样。

      事实上这种方式效率更快。有可能第一种方法也会很快,那是在对相关的每个字段都建立了索引的情况下,但是那显然不是一个好的注意。

      3.避免使用过多的“or

      如果有可能的话,尽量避免过多地使用or:

      WHERE a = "B" OR a = "C" 

      要比 

      WHERE a IN ("B","C"

      慢。

      有时甚至UNION会比OR要快。

     4.使用索引。      

        在所有的join和order by 的字段上建立索引。

        在where中的大多数字段建立索引。

        WHERE datecol >= "this/date" AND datecol 

          要比 

          WHERE datecol BETWEEN "this/date" AND "that/date" 慢       

      如何在shell脚本中使用一个sql查询的结果?

      以下的是一个运行在sh/ksh下面的脚本。在online中,如果你想要更新一个有许多表的数据库的统计信息。这个脚本不太好。因为这个脚本只能单个处理数据库中的表,而不能同时处理大量的表。

      例子:

      # update_em 

      # Run UPDATE STATISTICS on a table by table basis 

      # 

      DATABASE=$1 

      if [ -z "$DATABASE" ] 

      then 

      echo "usage: update_em dbname" >&2 

      exit 1 

      fi 

      isql $DATABASE -  dev/null | isql $DATABASE - 

      output to pipe "cat" without headings 

      select "update statistics for table ", tabname, ";" 

      from systables where tabid >= 100 order by tabname; 

      EOF

       exit 0        

      也许你已经注意到exit的返回值对不同的isql不是都相同,因此这样作不是很可靠,代替通过$?来检查返回值的更好的主意是将标准错误重定向到一个文件中,然后在这个文件中grep 

        “error。例如:

      # Generate the data 

      isql -qr $stage.err 

      database $database; 

      select ... 

      ! 

      # Check for errors 

      if grep -i "error" $stage.err >/dev/null 

      then

       ...error_handler... 

      fi

       

      为什么不能对一个计算产生的字段创建视图?

      问题:为什么我不能创建视图:

      CREATE VIEW tst AS 

      SELECT ship_charge - totval cout 

      FROM orders WHERE ship_charge > 0; 

      回答:你应该这样写:

      CREATE VIEW tst (cout) AS 

      SELECT ship_charge - totval 

      FROM orders WHERE ship_charge > 0;       

      如何只select 出数据库中的部分数据(例如10%)。

      问题:如果你想要得到一个select 语句正常返回的数据的一部分,例如:

      SELECT firstname, lastname, city, state 

      FROM bigdatabase 

      WHERE state = "TX"

      回答:

      有一个方法可以返回一个近似值,只需要在where后加上:

      AND rowid=(trunc(rowid/x)*x) 

      其中的x代表你想要返回的总的记录的1/x。需要说明的是,这种方法只能返回一个近似的值,并且表中的数据在物理上分布的连续性。       

      如何创建一个表结构和永久表完全一致的临时表。

      例如:CREATE TEMP TABLE mytemp (prodno LIKE product.prodno 

      desc LIKE product.desc) 

      你可以使用如下的语句:

      SELECT prodno, desc FROM product 

      WHERE ROWID = -1 

      INSERT INTO TEMP mytemp

    INFORMIX SQL 实践与技巧(2)

      如何更改serial类型下一次插入操作产生的值?

      我们知道serial类型的字段是系统自动增加的整数字段,那么怎样能控制下一个serial类型字段的值。

      想要下一个插入的serial类型的值比默认值大,可以用:

      ALTER TABLE tabname MODIFY( ser_col_name SERIAL([new_start_number])

      想要下一个插入的serial类型的值比默认的值要小,首先需要将serial类型重新置为1:

      INSERT INTO table (serial_column) valueS (2147483647); 

      INSERT INTO table (serial_column) valueS (0); -- 重新从1开始! 

      ....然后执行ALTER TABLE(就像上面的做法一样)。       

      如何在发生错误的时候终止sql脚本的执行?

      如果你创建了一个sql脚本,并且在UNIX命令行中使用以下的方式来执行这个脚本:

      $ dbaccess   <database> <脚本文件名>

      这时,脚本中的所有的sql语句都会被执行,即使其中的一个sql语句发生了错误。例如,如果你脚本中为如下的语句:

      BEGIN WORK; 

      INSERT INTO history 

      SELECT * 

      FROM current 

      WHERE month = 11; 

      DELETE FROM current 

      WHERE month = 11; 

      COMMIT WORK; 

      如果INSERT语句失败了,DELETE语句仍旧会继续执行。直到commit work。这样的后果可能会很严重。你可以通过设置一个环境变量来防止这种情况的发生。

      DBACCNOIGN=1

      如何设置decimal字段运算结果的精度?

      假定你使用dbaccess或者isql,设置环境变量DBFLTMASK=6 就可以设置为小数点后面6位,比如:

      CREATE TEMP TABLE t 

      ( col_a DECIMAL(8,4) NOT NULL, 

      col_b DECIMAL(8,4) NOT NULL, 

      col_c DECIMAL(8,4) NOT NULL 

      ); 

      INSERT INTO t valueS(1.2345, 3.4567, 5.6789); 

      SELECT (col_a + col_b) / col_c AS value FROM t; 

      value 0.826075 

      如果DBFLTMASK=7

      value 0.8260755

          为什么我们有时会遇到sysprocplan表被锁的提示?

      sysprocplan表是sysmaster库中的一个表,其中记录存储过程经过优化的查询计划。每当查询树中的数据库对象有任何结构上的变化,这个查询计划就会自动更新。如果对查询树中存在的任何表有update 

        statistics操作,也会自动更新查询计划。在查询计划更新的时候,会对sysporcplan表中的相关记录加锁。

      注意:每次你对一个表更新统计的时候,也同时会更新于这个表相关的存储过程,即UPDATE STATISTICS FOR PROCEDURE 。

 

      你可以作的另外一件事情就是:在存储过程中使用SET OPTIMIZATION LOW,这会让优化器在存储过程运行的时候不会试图去重新优化它。否则存储过程通常都会被重新优化一次。

      如何删除掉表中重复的记录?

      假设“keycol”字段的值唯一,而且没有对表进行分片,并且没有其它的人正在删除sometable中的记录,你可以执行如下的SQL:

      delete from sometable as a 

      where rowid  (select min(rowid) from sometable where keycol = a.keycol)

      如果这个表使用表分片,rowid不存在,你还可以用如下的方法:

      BEGIN WORK; 

      SELECT DISTINCT * FROM Table INTO TEMP Temp1; 

      DELETE FROM Table WHERE 1 = 1; 

      INSERT INTO Table SELECT * FROM Temp1; 

      COMMIT WORK;  

      对于规模较小或中等的表,并且你有足够的存储空间来存储整个的临时表的时候,这种方法通常十分有效。

      如何加快SELECT COUNT(DISTINCT)的速度。

      通常“SELECT COUNT(DISTINCT)”这样的操作要花费比较长的时间,如果你这样作:

      SELECT UNIQUE xxx INTO TEMP XXX " 然后再"SELECT COUNT(*) FROM TEMP XXX" 

      这样通常可以提高几倍的效率。

posted on 2008-07-18 16:52 joaquin25 阅读(1588) 评论(0)  编辑  收藏 所属分类: informix专题


只有注册用户登录后才能发表评论。


网站导航: