in

SDT Community Server

SDT Forums, Blogs, Photos server.

Coolboy

May 2008 - Posts

  • Unix/Linux中编辑文件的命令VI详细介绍

    Unix/Linux中编辑文件的命令VI详细介绍

    -=-=-=-=-=>

    VI命令可以说是Unix/Linux世界里最常用的编辑文件的命令了,但是因为它的命令集众多,很多人都不习惯使用它,其实您只需要掌握基.令,然后加以灵活运用,就会发现它的优势,并会逐渐喜欢使用这种方法。本文旨在介绍VI的一些最常用命令和高级应用技巧。




    一、基.令介绍



    ---- 1.光标命令



    k、j、h、l——上、下、左、右光标移动命令。虽然您可以在Linux中使用键盘右边的4个光标键,但是记住这4个命令还是非常有用的。这4个键正是右手在键盘上放置的基本位置。


    nG——跳转命令。n为行数,该命令立即使光标跳到指定行。

    Ctrl G——光标所在位置的行数和列数报告。

    w、b——使光标向前或向后跳过一个单词。

    ---- 2.编辑命令

    i、a、r——在光标的前、后以及所在处插入字符命令(i=insert、a=append、r=replace)。

    cw、dw——改变(置换)/删除光标所在处的单词的命令 (c=change、d=delete)。

    x、d$、dd——删除一个字符、删除光标所在处到行尾的所有字符以及删除整行的命令。

    ---- 3.查找命令

    ---- /string、?string——从光标所在处向后或向前查找相应的字符串的命令。

    ---- 4.拷贝复制命令

    ---- yy、p——拷贝一行到剪贴板或取出剪贴板中内容的命令。



    二、常见问题及应用技巧



    ---- 1.在一个新文件中读/etc/passwd中的内容,取出用户名部分。

    ---- vi file

    ---- :r /etc/passwd 在打开的文件file中光标所在处读入/etc/passwd

    ---- :%s/:.*//g 删除/etc/passwd中用户名后面的从冒号开始直到行尾的所有部分。

    ---- 您也可以在指定的行号后读入文件内容,例如使用命令“:3r /etc/passwd”从新文件的第3行开始读入 /etc/passwd的所有内容。


    ---- 我们还可以使用以下方法删掉文件中所有的空行及以#开始的注释行。

    ---- #cat squid.conf.default | grep -v '^$' | grep -v '^#'



    ---- 2.在打开一个文件编辑后才知道登录的用户对该文件没有写的权限,不能存盘,需要将所做修改存入临时文件。

    ---- vi file

    ---- :w /tmp/1 保存所做的所有修改,也可以将其中的某一部分修改保存到临时文件,例如仅仅把第20~59行之间的内容存盘成文件/tmp/1,我们可以键入如下命令。


    ---- vi file

    ---- :20,59w /tmp/1



    ---- 3.用VI编辑一个文件,但需要删除大段的内容。

    ---- 首先利用编辑命令“vi file”打开文件,然后将光标移到需要删除的行处按Ctrl G显示行号,再到结尾处再按Ctrl G,显示文件结尾的行号。


    ---- :23,1045d 假定2次得到的行号为23和1045,则把这期间的内容全删除,也可以在要删除的开始行和结束行中用ma、mb命令标记,然后利用“:'a,'bd”命令删除。




    ---- 4.在整个文件的各行或某几行的行首或行尾加一些字符串。

    ---- vi file

    ---- :3,$s/^/some string / 在文件的第一行至最后一行的行首插入“some string”。

    ---- :%s/$/some string/g 在整个文件每一行的行尾添加“some string”。

    ---- :%s/string1/string2/g 在整个文件中替换“string1”成“string2”。

    ---- :3,7s/string1/string2/ 仅替换文件中的第3行到第7行中的“string1”成“string2”。

    ---- 注意: 其中s为substitute,%表示所有行,g表示global。



    ---- 5.同时编辑2个文件,拷贝一个文件中的文本并粘贴到另一个文件中。

    ---- vi file1 file2

    ---- yy 在文件1的光标处拷贝所在行

    ---- :n 切换到文件2 (n=next)

    ---- p 在文件2的光标所在处粘贴所拷贝的行

    ---- :n 切换回文件1



    ---- 6.替换文件中的路径。

    ---- 使用命令“:%s#/usr/bin#/bin#g”可以把文件中所有路径/usr/bin换成/bin。也可以使用命令“:%s//usr/bin//bin/g”实现,其中“”是转义字符,表明其后的“/”字符是具有实际意义的字符,不是分隔符。
    Posted May 30 2008, 10:11 AM by Coolboy with no comments
    Filed under:
  • linux的rar命令 安装和使用

    关于linuxrar命令的安装和使用, 某些时候还是有这个必要的, 比如某些客户已经用ftp把一个超大的rar文件传了上去, 要求你去解压的时候

    首先下载rarlinux-3.7.1.tar.gz

    点击下载


    2然后解压
    # tar xvfz    rarlinux-3.7.b1.tar.gz
    3安装
    # make install
    mkdir -p /usr/local/bin
    mkdir -p /usr/local/lib
    cp rar unrar /usr/local/bin
    cp rarfiles.lst /etc
    cp default.sfx /usr/local/lib
    4解压文件:

    # rar x test.rar /
    rar: /lib/tls/libc.so.6: version `GLIBC_2.4' not found (required by rar)

    5需要GLIBC_2.4。如果没有GLIBC_2.4可以

    # cp ./rar/rar_static /usr/local/bin/rar

    rar_static 版是 static linking 版本,不会有 glibc 程式库版本不和的问题。

    再次解压:
    [root@xxxx ~]# rar x test.rar /
    RAR 3.71   Copyright (c) 1993-2007 Alexander Roshal   20 Sep 2007
    Shareware version         Type RAR -? for help

    Extracting from test.rar
    Extracting  /test.txt                                                 OK
    All OK

    6打包
    rar a install.rar ./install.log

    这样就可以了

    Posted May 28 2008, 02:31 PM by Coolboy with no comments
    Filed under:
  • Linux菜鸟入门级命令3344

    1. man 对你熟悉或不熟悉的命令提供帮助解释

    eg:man ls 就可以查看ls相关的用法

    注:按q键或者ctrl+c退出,在linux下可以使用ctrl+c终止当前程序运行。

    2. ls 查看目录或者文件的属*,列举出任一目录下面的文件

    eg: ls /usr/man

    ls -l

    a.d表示目录(directory),如果是一个"-"表示是文件,如果是l则表示是一个连接文件(link)

    b.表示文件或者目录许可权限.分别用可读(r),可写(w),可运行(x)。

    3. cp 拷贝文件

    eg: cp filename1 filename2 //把filename1拷贝成filename2

    cp 1.c netseek/2.c //将1.c拷到netseek目录下命名为2.c

    4. rm 删除文件和目录

    eg: rm 1.c //将1.c这个文件删除

    5. mv 移走目录或者改文件名

    eg: mv filename1 filename2 //将filename1 改名为filename2

    mv qib.tgz ../qib.tgz //移到上一级目录

    6. cd 改变当前目录 pwd 查看当前所在目录完整路径

    eg: pwd //查看当前所在目录路径

    cd netseek //进入netseek这个目录

    cd //退出当前目录

    7. cat,more命令

    将某个文件的内容显示出来。两个命令所不同的是:cat把文件内容一直打印出来,而 more则分屏显示

    eg; cat>1.c //就可以把代码粘帖到1.c文件里,按ctrl+d 保存代码。

    cat 1.c 或more 1.c //都可以查看里面的内容。

    gcc -o 1 1.c //将1.c编译成.exe文件,我们可以用此命编译出代码。

    8.chmod 命令 权限修改 用法:chmod 一位8进制数 filename。

    eg: chmod u+x filenmame //只想给自己运行,别人只能读

    //u表示文件主人, g 表示文件文件所在组。 o 表示其他人 ;r 表可读,w 表可写,x 表可以运行

    chmod g+x filename //同组的人来执行

    9. clear,date命令

    clear:清屏,相当与DOS下的cls;date:显示当前时间。

    10. mount 加载一个硬件设备

    用法:mount [参数] 要加载的设备 载入点

    eg: mount /dev/cdrom

    cd /mnt/cdrom //进入光盘目录

    11. su 在不退出登陆的情况下,切换到另外一个人的身份

    用法: su -l 用户名(如果用户名缺省,则切换到root状态)

    eg:su -l netseek (切换到netseek这个用户,将提示输入密码)

    12.whoami,whereis,which,id

    //whoami:确认自己身份

    //whereis:查询命令所在目录以及帮助文档所在目录

    //which:查询该命令所在目录(类似whereis)

    //id:打印出自己的UID以及GID。(UID:用户身份唯一标识。GID:用户组身份唯一标识。每一个用户只能有一个唯一的UID和 GID)

    eg: whoami //显示你自已登陆的用户名

    whereis bin 显示bin所在的目录,将显示为:/usr/local/bin

    which bin

    13. grep,find

    grep:文本内容搜索;find:文件或者目录名以及权限属主等匹配搜索

    eg: grep success *    /*查找当前目录下面所有文件里面含有success字符的文件

    14. kill 可以杀死某个正在进行或者已经是dest状态的进程

    eg; ps ax

    15. passwd 可以设置口令

    16. history 用户用过的命令

    eg: history //可以显示用户过去使用的命令

    17. !! 执行最近一次的命令

    18. mkdir命令

    eg: mkdir netseek //创建netseek这个目录

    19. tar 解压命令

    eg: tar -zxvf nmap-3.45.tgz //将这个解压到nmap-3.45这个目录里

    20. finger 可以让使用者查询一些其他使用者的资料

    eg: finger //查看所用用户的使用资料

    finger root //查看root的资料

    Posted May 28 2008, 01:35 PM by Coolboy with no comments
    Filed under:
  • Linux命令集2

    Linux命令集

    整理:Jims of 肥肥世家

    发布时间:2004年7月20日

    更新时间:2005年03月16日

    Abstract

    在安装、使用和维护Linux系统中,我们都会用到大量的命令,而且命令参数繁多,这也可说是linux系统的一大特色,所以经常会忘记。这里记录我使用Linux当中用到过的命令,用于备查。


    1. 最常用的命令列表

    下面列出十个在使用linux过程中使用频率最高的命令。这里只作简单介绍,具体用法请参考后面内容。

    • cat,显示文件内容。

    • cd,改变目录路径。

    • cp,复制文件。

    • find,查找文件。

    • grep,搜索、过滤信息。

    • ls,列出目录信息。

    • more,分页显示。

    • rm,删除文件或目录。

    • vi,调用vi文本编辑器。

    • who,显示登录用户信息。

    2. chmod----改变一个或多个文件的存取模式(mode)

    chmod [options] mode files

    只能文件属主或特权用户才能使用该功能来改变文件存取模式。mode可以是数字形式或以who opcode permission形式表示。who是可选的,默认是a(所有用户)。只能选择一个opcode(操作码)。可指定多个mode,以逗号分开。

    • options:

      -c,--changes

      只输出被改变文件的信息

      -f,--silent,--quiet

      当chmod不能改变文件模式时,不通知文件的用户

      --help

      输出帮助信息。

      -R,--recursive

      可递归遍历子目录,把修改应到目录下所有文件和子目录

      --reference=filename

      参照filename的权限来设置权限

      -v,--verbose

      无论修改是否成功,输出每个文件的信息

      --version

      输出版本信息。

    • who

      u

      用户

      g

      o

      其它

      a

      所有用户(默认)

    • opcode

      +

      增加权限

      -

      删除权限

      =

      重新分配权限

      permission

      r

      w

      x

      执行

      s

      设置用户(或组)的ID号

      t

      设置粘着位(sticky bit),防止文件或目录被非属主删除

      u

      用户的当前权限

      g

      组的当前权限

      o

      其他用户的当前权限

    • 作为选择,我们多数用三位八进制数字的形式来表示权限,第一位指定属主的权限,第二位指定组权限,第三位指定其他用户的权限,每位通过4(读)、2(写)、1(执行)三种数值的和来确定权限。如6(4+2)代表有读写权,7(4+2+1)有读、写和执行的权限。

    • 还可设置第四位,它位于三位权限序列的前面,第四位数字取值是4,2,1,代表意思如下:

      • 4,执行时设置用户ID,用于授权给基于文件属主的进程,而不是给创建此进程的用户。

      • 2,执行时设置用户组ID,用于授权给基于文件所在组的进程,而不是基于创建此进程的用户。

      • 1,设置粘着位。

    • 实例:

      $ chmod u+x file                给file的属主增加执行权限
      $ chmod 751 file                给file的属主分配读、写、执行(7)的权限,给file的所在组分配读、执行(5)的权限,给其他用户分配执行(1)的权限
      $ chmod u=rwx,g=rx,o=x file    上例的另一种形式
      $ chmod =r file                为所有用户分配读权限
      $ chmod 444 file               同上例
      $ chmod a-wx,a+r               同上例
      $ chmod -R u+r directory       递归地给directory目录下所有文件和子目录的属主分配读的权限
      $ chmod 4755                   设置用ID,给属主分配读、写和执行权限,给组和其他用户分配读、执行的权限。
      

    3. chgrp----修改文件或目录的所属组

    chgrp [options] newgroup files/directorys

    组名可以用组的ID号,也可用/etc/group中的组名。只有文件的属主或特权用户(root)才可改变它的组。

    • options:

      -c,--changes

      只输出被改变文件的信息

      -f,--silent,--quiet

      当不能改变文件组属性时,不通知文件的用户

      --help

      输出帮助信息。

      -R,--recursive

      可递归遍历子目录,把修改应到目录下所有文件和子目录

      --reference=filename

      参照filename的组信息来设置当前文件的组

      -v,--verbose

      输出详细信息

      --version

      输出版本信息。

    • 实例:

      $ chgrp root test           把test的所属组更改root组
      $ chgrp -R mysql test       递归地把test目录及该目录下所有文件和子目录的组属性设置成mysql
      $ chgrp root *              把当前目录中所有文件的组属性设置成root
      

    4. chown----设置一个或多个文件或目录的属主身份

    chown [options] newowner files/directorys

    新的属主可以是用户的ID号,也可以是/etc/passwd里的登录名。chown也可接受这样的形式:newowner:newgroup或newowner.newgroup。同时改变所属组的属性。如果句点和冒号后没有组名,则组改变为新属主的组。只有文件或目录的当前属主才有权改变它的属性。

    • options:

      -c,--changes

      只输出被改变文件的信息

      --dereference

      跟踪符号链接

      -h,--no-dereference

      改变每一个符号链的属主身份,而不是被引用文件的属主身份

      -f,--silent,--quiet

      当不能改变文件属主属性时,不通知文件的用户

      --help

      输出帮助信息。

      -R,--recursive

      可递归遍历子目录,把修改应到目录下所有文件和子目录

      --reference=filename

      把属主改变成filename文件的属主

      -v,--verbose

      输出详细信息

      --version

      输出版本信息。

    • 实例:

      $ chown  root test                       把test文件的属主改进root
      $ chown -R root test_directory           递归地把test_directory目录下的所有文件属主改成root
      $ chown --dereference root test_link     把test_link链接的原文件属主改成root,链接文件属主不变
      $ chown --no-dereference root test_link  把test_link的链接文件属主改成root,原文件属主不变
      

    5. date----显示、修改系统时间

    date [options][+format][date]

     

    $ date -s 06/09/2004	修改日期(按月日年格式)
    $ date -s 13:56:00	修改时间(按时分秒格式)
    $ date -r test		显示test文件最后一次的修改时间
    $ date +'%Y-%m-%d'	以yyyy-mm-dd格式显示日期,其它格式请参考帮助
    $ clock -r		查询BIOS时间
    $ clock -w		把修改后的时间写回BIOS
    			  
    		  

     

    6. df-----显示已安装文件系统的磁盘容量状态

    df [options][name]

     

    $ df -h		以友好的格式输出所有已安装文件系统的磁盘容量状态
    $ df -m /home	以M为单位输出home目录的磁盘容量状态
    $ df -k		以K为单位输出所有已安装文件系统的磁盘容量状态
    $ df -i		报告空闲的、用过的或部份用过的(百份比)索引节点
    $ df -t ext3	仅显示文件类型为ext3的文件系统的磁盘状态
    $ df -x ext3	仅显示文件类型不为ext3的文件系统的磁盘状态
    $ df -T		除显示文件系统磁盘容量大小外还显示文件系统类型
    $ df -l		仅显示本地文件系统。
    			  
    		  

     

    7. fdisk----分区表查询工具

    fdisk [options][driver]

    $ fdisk -l          列出所有分区信息
    

    8. hdparm----硬盘管理

    hdparm [options][driver]

     

    $ hdparm -d  /dev/hda           显示硬盘的DMA模式是不打开,1代表on
    $ hdparm -tT /dev/hda           测试硬盘的写性能
    $ hdparm -d1 /dev/hda		开启dma功能
    $ hdparm -d1 -X68 -c3 -m16 /dev/hda  
    选项说明:
    -c3:把硬盘的IO模式从16位转成32位。
    -m16:改变硬盘的多路扇区的读功能,-m16使硬盘在一次I/O中断中读入16个扇区的数据。
    -d1:打开DMA模式。
    -X68:支持ATA66的数据传输模式。下面是其它模式的设置对照
    ATA33.......参数是-X66 
    ATA66.......参数是-X68 
    ATA100......参数是-X69
    $ hdparm -k1 /dev/hda            保存设置
    			  
    		  

     

    9. ln-----为文件建立别名

    ln [options] sourcename [destname]

    ln [options] sourcenames destdirectory

     

    $ ln -s file1 file2       建立一个到file1的符号链接file2,删除file2不会影响file1
    $ ln -s -f file1 file2    建立一个到file1的符号链接file2,并不提示是否重写
    

     

    10. shutdown-----终止所有进程序,关闭计算机。

    shutdown [options] when [message]

    用when可以是指定的关机时间(以hh:mm格式)、关机前要等待的时间(以+m格式)、或者now。message指定一条广播消息通知所有用户退出系统。showdown给所有进程发送SIGTERM信号,并调用init 1执行实际的关机动作。

    $ shutdown -c          取消正在进行的关闭操作
    $ shutdown -f          快速重新启动,在重新启动时禁止对fsck的常规调用
    $ shutdown -h          当关闭完成时停止系统
    $ shutdown -k          输出警告信息,但禁止实际的关闭
    $ shutdown -n          不调用init就执行关闭
    $ shutdown -r          当关闭完成时重新启动系统
    $ shutdown -t 5        在杀死进程和改变运行级别之间确保延时5秒
    

    11. sleep-----执行另一个命令之前等待的时间

    sleep amount [units]

    units默认为秒(s),m表示分钟,h表示小时,d表示天。

    12. swapon/swapoff-----启动和关闭交换分区

    swapon/swapoff [options] device

    $ swapon -s            显示交换分区信息
    $ swapon -a            激活所有在/etc/fstab中有sw标记的分区
    $ swapon -p 1          设置交换分区优先级为1
    

    13. tune2fs-----调整Linux第二扩展文件系统的参数

    tune2fs [options] device

    $ tune2fs -l /dev/hda1       显示hda1分区的超级块内容
    $ tune2fs -c 100 /dev/hda1   设置hda1分区每mount100次就进行磁盘检查
    

    14. uniq----过滤、统计、删除重复行

    uniq [options][file1 [files]]

     

    $ uniq -c file		file中的重复行输出一次,并在每行前显示重复次数
    $ uniq -d file		file中的重复行输出一次,但不输出唯一的行
    $ uniq -u file          只输出file中的唯一行
    $ uniq file1 file2	把file1中的重复的相邻行删除,并把每行的一个拷贝送到file2
    			  
    		  

     

    15. wc-----输出每个文件中的字符数、单词数及行数。

    wc [options][files]

     

    $ wc -l file		输出file中的行数
    $ wc -w file		输出file中的单词数
    $ wc -c file		输出file中的字符数
    			  
    		  

     

  • 扫盲行动之一:Linux常用命令简介

    su

    su命令是最基本的命令之一,常用于不同用户间切换。例如,如果登录为 user1,要切换为user2,只要用如下命令:

    $su user2

    然后系统提示输入user2口令,输入正确的口令之后就可以切换到user2。完成之后就可以用exit命令返回到user1。

    su命令的常见用法是变成根用户或超级用户。如果发出不带用户名的su命令 ,则系统提示输入根口令,输入之后则可切换为根用户。

    如果登录为根用户,则可以用su命令成为系统上任何用户而不需要口令。

    pwd

    pwd命令也是最常用最基本的命令之一,用于显示用户当前所在的目录。

    cd

    cd命令不仅显示当前状态,还改变当前状态,它的用发跟dos下的cd命令基本一致。

    cd ..可进入上一层目录

    cd -可进入上一个进入的目录

    cd ~可进入用户的home目录

    ls

    ls命令跟dos下的dir命令一样,用于显示当前目录的内容。

    如果想取得详细的信息,可用ls -l命令, 这样就可以显示目录内容的详细信息。

    如果目录下的文件太多,用一屏显示不了,可以用ls -l |more分屏显示 。

    find

    find命令用于查找文件。这个命令可以按文件名、建立或修改日期、所有者(通常是建立文件的用户)、文件长度或文件类型进行搜索。

    find命令的基本结构如下:

    $find

    其中指定从哪个目录开始搜索。指定搜索条件。表示找到文件怎么处理。一般来说,要用-print动作,显示 整个文件路径和名称。如果没有这个动作,则find命令进行所要搜索而不显示结果,等于白费劲。

    例如,要搜索系统上所有名称为ye的文件,可用如下命令:

    $find / -name ye -print

    这样就可以显示出系统上所有名称为ye的文件。

    tar

    tar最初用于建立磁带备份系统,目前广泛用于建立文件发布档案。可用如下方法建立tar档案:

    $tar cvf

    例如,如果要将当前目录中所有文件存档到ye.tar中,可用如下命令:

    $tar cvf ye.tar *.*

    要浏览档案内容,将c选项变成t。如果要浏览ye.tar档案中的内容,可用如下命令:

    $tar tvf ye.tar

    要取出档案内的内容,将c选项变成x。如果要将ye.tar档案中的内容取到当前目录中,可用如下命令:

    $tar xvf ye.tar

    gzip

    gzip命令用于压缩文件。 例如,如果要将ye.txt文件压缩,可用如下命令:

    $gzip ye.txt

    这样就可以压缩文件并在文件名后面加上gz扩展名,变成文件ye.txt.gz。

    解压缩文件可用gzip -d命令实现:

    $gzip -d ye.txt.gz

    这样就可以解压缩文件并删除gz扩展名。除此之外还可以用gunzip命令来解 压缩文件,效果跟用gzip -d命令一样。

    旧版的tar命令不压缩档案,可用gzip压缩。例如:

    $tar cvf ye.tar *.txt

    $gzip ye.tar

    则可建立压缩档案ye.tar.gz。

    新版的tar可以直接访问和建立gzip压缩的tar档案,只要在tar命令中加上z 选项就可以了。例如:

    $tar czvf ye.tar *.txt

    生成压缩档案ye.tar.gz,

    $tar tzvf ye.tar *.txt

    显示压缩档案ye.tar.gz的内容,而

    $tar xzvf ye.tar *.txt

    取出压缩档案ye.tar.gz的内容。

    mkdir

    这个命令很简单,跟dos的md命令用法几乎一样,用于建立目录。

    cp

    cp命令用于复制文件或目录。

    cp命令可以一次复制多个文件,例如:

    $cp *.txt *.doc *.bak /home

    将当前目录中扩展名为txt、doc和bak的文件全部复制到/home目录中。

    如果要复制整个目录及其所有子目录,可以用cp -R命令。

    rm

    rm命令用于删除文件或目录。

    rm命令会强制删除文件,如果想要在删除时提示确认,可用rm -i命令。

    如果要删除目录,可用rm -r命令。rm -r命令在删除目录时,每删除一个文件或目录都会显示提示,如果目录太大,响应每个提示是不现实的。这时可以用 rm -rf命令来强制删除目录,这样即使用了-i标志也当无效处理。

    mv

    mv命令用于移动文件和更名文件。例如:

    $mv ye.txt /home

    将当前目录下的ye.txt文件移动到/home目录下,

    $mv ye.txt ye1.txt

    将ye.txt文件改名为ye1.txt。

    类似于跟cp命令,mv命令也可以一次移动多个文件,在此不再赘叙。

    reboot

    重启命令,不必多说。

    halt

    关机命令,不必多说。

  • oracle中查询时指定索引的方法,优化是一种学问

    oracle中查询时指定索引的方法
    2008-01-11 16:00

    五、索引Index的优化设计

    1、管理组织索引

             索引可以大大加快数据库的查询速度,索引把表中的逻辑值映射到安全的RowID,因此索引能进行快速定位数据的物理地址。但是有些DBA发现,对一个大 型表建立的索引,并不能改善数据查询速度,反而会影响整个数据库的性能。这主要是和SGA的数据管理方式有关。ORACLE在进行数据块高速缓存管理时, 索引数据比普通数据具有更高的驻留权限,在进行空间竞争时,ORACLE会先移出普通数据。对一个建有索引的大型表的查询时,索引数据可能会用完所有的数 据块缓存空间,ORACLE不得不频繁地进行磁盘读写来获取数据,因此在对一个大型表进行分区之后,可以根据相应的分区建立分区索引。如果对这样大型表的 数据查询比较频繁,或者干脆不建索引。另外,DBA创建索引时,应尽量保证该索引最可能地被用于where子句中,如果对查询只简单地制定一个索引,并不 一定会加快速度,因为索引必须指定一个适合所需的访问路径。2、聚簇的使用

    Oracle提供了另一种方法来提高查询速度,就是聚簇(Cluster)。所谓聚簇,简单地说就是把几个表放在一起,按一定公共属性混合存放。聚簇根 据共同码值将多个表的数据存储在同一个Oracle块中,这时检索一组Oracle块就同时得到两个表的数据,这样就可以减少需要存储的Oracle块, 从而提高应用程序的性能。

    3、优化设置的索引,就必须充分利用才能加快数据库访问速度。ORACLE要使用一个索引, 有一些最基本的条件:1)、where子名中的这个字段,必须是复合索引的第一个字段;2)、where子名中的这个字段,不应该参与任何形式的计算。 Sal*(2*90/100)

    六、多CPU和并行查询PQO(Parallel Query Option)方式的利用

    1、尽量利用多个CPU处理器来执行事务处理和查询

    CPU的快速发展使得ORACLE越来越重视对多CPU的并行技术的应用,一个数据库的访问工作可以用多个CPU相互配合来完成,加上分布式计算已经相 当普遍,只要可能,应该将数据库服务器和应用程序的CPU请求分开,或将CPU请求从一个服务器移到另一个服务器。对于多CPU系统尽量采用 Parallel Query Option(PQO,并行查询选项)方式进行数据库操作。

    2、使用Parallel Query Option(PQO,并行查询选择)方式进行数据查询

       使用PQO方式不仅可以在多个CPU间分配SQL语句的请求处理,当所查询的数据处于不同的磁盘时,一个个独立的进程可以同时进行数据读取。

    3、使用SQL*Loader Direct Path选项进行大量数据装载

    使用该方法进行数据装载时,程序创建格式化数据块直接写入数据文件中,不要求数据库内核的其他I/O。

    七、实施系统资源管理分配计划

    ORACLE提供了Database Resource Manager(DRM,数据库资源管理器)来控制用户的资源分配,DBA可以用它分配用户类和作业类的系统资源百分比。在一个OLDP系统中,可给联机 用户分配75%的CPU资源,剩下的25%留给批用户。另外,还可以进行CPU的多级分配。除了进行CPU资源分配外,DRM还可以对资源用户组执行并行 操作的限制。

    八、使用最和SQL优化方优的数据库连接案

    1、使用直接的OLE DB数据库连接方式。

    通过ADO可以使用两种方式连接数据库,一种是传统的ODBC方式,一种是OLE DB方式。ADO是建立在OLE DB技术上的,为了支持ODBC,必须建立相应的OLE DB到ODBC的调用转换,而使用直接的OLE DB方式则不需转换,从而提高处理速度。

    2、使用Connection Pool机制

    在数据库处理中,资源花销最大的是建立数据库连接,而且用户还会有一个较长的连接等待时间。解决的办法就是复用现有的Connection,也就是使用Connection Pool对象机制。

    Connection Pool的原理是:IIS+ASP体系中维持了一个连接缓冲池,这样,当下一个用户访问时,直接在连接缓冲池中取得一个数据库连接,而不需重新连接数据库,因此可以大大地提高系统的响应速度。

    3、高效地进行SQL语句设计

    通常情况下,可以采用下面的方法优化SQL对数据操作的表现:

    (1)减少对数据库的查询次数,即减少对系统资源的请求,使用快照和显形图等分布式数据库对象可以减少对数据库的查询次数。

    (2)尽量使用相同的或非常类似的SQL语句进行查询,这样不仅充分利用SQL共享池中的已经分析的语法树,要查询的数据在SGA中命中的可能性也会大大增加。

    (3)限制动态SQL的使用,虽然动态SQL很好用,但是即使在SQL共享池中有一个完全相同的查询值,动态SQL也会重新进行语法分析。

    (4)避免不带任何条件的SQL语句的执行。没有任何条件的SQL语句在执行时,通常要进行FTS,数据库先定位一个数据块,然后按顺序依次查找其它数据,对于大型表这将是一个漫长的过程。

    (5)如果对有些表中的数据有约束,最好在建表的SQL语句用描述完整性来实现,而不是用SQL程序中实现。

    (6)可以通过取消自动提交模式,将SQL语句汇集一组执行后集中提交,程序还可以通过显式地用COMMIT和ROLLBACL进行提交和回滚该事务。

    (7)检索大量数据时费时很长,设置行预取数则能改善系统的工作表现,设置一个最大值,当SQL语句返回行超过该值,数值库暂时停止执行,除非用户发出新的指令,开始组织并显示数据,而不是让用户继续等待。

    九、充分利用数据的后台处理方案减少网络流量

    1、合理创建临时表或视图

    所谓创建临时表或视图,就是根据需要在数据库基础上创建新表或视图,对于多表关联后再查询信息的可建新表,对于单表查询的可创建视图,这样可充分利用数 据库的容量大、可扩充性强等特点,所有条件的判断、数值计算统计均可在数据库服务器后台统一处理后追加到临时表中,形成数据结果的过程可用数据库的过程或 函数来实现。

    2、数据库打包技术的充分利用

    利用数据库描述语言编写数据库的过程或函数,然后把过程或函数打成包在数据库后台统一运行包即可。

    3、数据复制、快照、视图,远程过程调用技术的运用

    数据复制,即将数据一次复制到本地,这样以后的查询就使用本地数据,但是只适合那些变化不大的数据。使用快照也可以在分布式数据库之间动态复制数据,定义 快照的自动刷新时间或手工刷新,以保证数据的引用参照完整性。调用远程过程也会大大减少因频繁的SQL语句调用而带来的网络拥挤。

        总之,对所有的性能问题,没有一个统一的解决方法,但ORACLE提供了丰富的选择环境,可以从ORACLE数据库的体系结构、软件结构、模式对象 以及具体的业务和技术实现出发,进行统筹考虑。提高系统性能需要一种系统的整体的方法,在对数据库进行优化时,应对应用程序、I/O子系统和操作系统 (OS)进行相应的优化。优化是有目的地更改系统的一个或多个组件,使其满足一个或多个目标的过程。对Oracle来说,优化是进行有目的的调整组件级以 改善性能,即增加吞吐量,减少响应时间。如果DBA能从上述九个方面综合考虑优化方案,相信多数ORACLE应用可以做到按最优的方式来存取数据。

     

     

    我们要做到不但会写SQL,还要做到写出性能优良的SQL,以下为笔者学习、摘录、并汇总部分资料与大家分享!

    (1)      选择最有效率的表名顺序(只在基于规则的优化器中有效):

    ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。

    如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.把数据少的表放在FROM后面的最后

    (2)      WHERE子句中的连接顺序.:

    ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.

    (3)      SELECT子句中避免使用 ‘ * ‘:

    ORACLE在解析的过程中, 会将'*' 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间

    (4)      减少访问数据库的次数:

    ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等;

    (5)      在SQL*Plus , SQL*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议值为200

    (6)      使用DECODE函数来减少处理时间:******************************

    使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.

     

    decode (expression, search_1, result_1)

    decode (expression, search_1, result_1, search_2, result_2)

    decode (expression, search_1, result_1, search_2, result_2, ...., search_n, result_n)

     

    decode (expression, search_1, result_1, default)

    decode (expression, search_1, result_1, search_2, result_2, default)

    decode (expression, search_1, result_1, search_2, result_2, ...., search_n, result_n, default)

    decode函数比较表达式和搜索字,如果匹配,返回结果;如果不匹配,返回default值;如果未定义default值,则返回空值。

    以下是一个简单测试,用于说明Decode函数的用法:

     

    SQL> create table t as select username,default_tablespace,lock_date from dba_users;

     

    Table created.

     

    SQL> select * from t;

    USERNAME                       DEFAULT_TABLESPACE             LOCK_DATE

    ------------------------------ ------------------------------ ---------

    SYS                            SYSTEM

    SYSTEM                         SYSTEM

    OUTLN                          SYSTEM

    CSMIG                          SYSTEM

    SCOTT                           SYSTEM

    EYGLE                          USERS

    DBSNMP                         SYSTEM

    WMSYS                          SYSTEM                         20-OCT-04

     

    8 rows selected.

     

     

    SQL> select username,decode(lock_date,null,'unlocked','locked') status from t;

     

    USERNAME                       STATUS

    ------------------------------ --------

    SYS                            unlocked

    SYSTEM                         unlocked

    OUTLN                          unlocked

    CSMIG                          unlocked

    SCOTT                          unlocked

    EYGLE                          unlocked

    DBSNMP                         unlocked

    WMSYS                          locked

     

    8 rows selected.

     

    SQL> select username,decode(lock_date,null,'unlocked') status from t;

     

    USERNAME                       STATUS

    ------------------------------ --------

    SYS                            unlocked

    SYSTEM                         unlocked

    OUTLN                          unlocked

    CSMIG                          unlocked

    SCOTT                           unlocked

    EYGLE                          unlocked

    DBSNMP                         unlocked

    WMSYS

    8 rows selected.

    (7)      整合简单,无关联的数据库访问:

    如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)

    (8)      删除重复记录:

    最高效的删除重复记录方法 ( 因为使用了ROWID)例子:

    DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID)

    FROM EMP X WHERE X.EMP_NO = E.EMP_NO);

    (9)      用TRUNCATE替代DELETE:

    当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况) 而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,执行时间也会很短. (译者按: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)

    (10) 尽量多使用COMMIT:

    只要有可能,在程序中尽量多使用COMMIT, 这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少:

    COMMIT所释放的资源:

    a. 回滚段上用于恢复数据的信息.

    b. 被程序语句获得的锁

    c. redo log buffer 中的空间

    d. ORACLE为管理上述3种资源中的内部花费

    (11) 用Where子句替换HAVING子句:

    避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销. (非oracle中)on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后,因为on是先把不 符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的,where也应该比having快点的,因为它过滤数据后 才进行sum,在两个表联接时才用on的,所以在一个表的时候,就剩下where跟having比较了。在这单表查询统计的情况下,如果要过滤的条件没有 涉及到要计算字段,那它们的结果是一样的,只是where可以使用rushmore技术,而having就不能,在速度上后者要慢如果要涉及到计算的字 段,就表示在没计算之前,这个字段的值是不确定的,根据上篇写的工作流程,where的作用时间是在计算之前就完成的,而having就是在计算后才起作 用的,所以在这种情况下,两者的结果会不同。在多表联接查询时,on比where更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表 后,再由where进行过滤,然后再计算,计算完后再由having进行过滤。由此可见,要想过滤条件起到正确的作用,首先要明白这个条件应该在什么时候 起作用,然后再决定放在那里

    (12) 减少对表的查询:

    在含有子查询的SQL语句中,要特别注意减少对表的查询.例子:

                    SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT

    TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)

    (13) 通过内部函数提高SQL效率.:

    复杂的SQL往往牺牲了执行效率. 能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的

    (14) 使用表的别名(Alias):

    当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误.

    (15) 用EXISTS替代IN、用NOT EXISTS替代NOT IN:

    在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率. 在子查询中,NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历). 为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS.

    例子:

    (高效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND EXISTS (SELECT 1 FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB')

    (低效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB')

    (16) 识别'低效执行'的SQL语句:

    虽然目前各种关于SQL优化的图形化工具层出不穷,但是写出自己的SQL工具来解决问题始终是一个最好的方法:

    SELECT EXECUTIONS , DISK_READS, BUFFER_GETS,

    ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio,

    ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,

    SQL_TEXT

    FROM V$SQLAREA

    WHERE EXECUTIONS>0

    AND BUFFER_GETS > 0

    AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8

    ORDER BY 4 DESC;

    (17) 用索引提高效率:

    索引是表的一个概念部分,用来提高检索数据的效率,ORACLE使用了一个复杂的自平衡B- tree结构. 通常,通过索引查询数据比全表扫描要快. 当ORACLE找出执行查询和Update语句的最佳路径时, ORACLE优化器将使用索引. 同样在联结多个表时使用索引也可以提高效率. 另一个使用索引的好处是,它提供了主键(primary key)的唯一性验证.。那些LONG或LONG RAW数据类型, 你可以索引几乎所有的列. 通常, 在大型表中使用索引特别有效. 当然,你也会发现, 在扫描小表时,使用索引同样能提高效率. 虽然使用索引能得到查询效率的提高,但是我们也必须注意到它的代价. 索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时, 索引本身也会被修改. 这意味着每条记录的INSERT , DELETE , UPDATE将为此多付出4 , 5 次的磁盘I/O . 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢.。定期的重构索引是有必要的.:在“系统维护清理”里有个“垃圾文件清 理”

    ALTER INDEX REBUILD

    (18) 用EXISTS替换DISTINCT:

    当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换, EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果. 例子:

           (低效):

    SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E

    WHERE D.DEPT_NO = E.DEPT_NO

    (高效):

    SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X'

    FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);

    (19) sql语句用大写的;因为oracle总是先解析sql语句,把小写的字母转换成大写的再执行

    (20) 在java代码中尽量少用连接符“+”连接字符串!

    (21) 避免在索引列上使用NOT 通常, 

    我们要避免在索引列上使用NOT, NOT会产生在和在索引列上使用函数相同的影响. 当ORACLE”遇到”NOT,他就会停止使用索引转而执行全表扫描.

    (22) 避免在索引列上使用计算.

    WHERE子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描.

    举例:

    低效:

    SELECT … FROM DEPT WHERE SAL * 12 > 25000;

    高效:

    SELECT … FROM DEPT WHERE SAL > 25000/12;

    (23) 用>=替代>

    高效:

    SELECT * FROM EMP WHERE DEPTNO >=4

    低效:

    SELECT * FROM EMP WHERE DEPTNO >3

    两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录.

    (24) 用UNION替换OR (适用于索引列)

    通常情况下, 用UNION替换WHERE子句中的OR将会起到较好的效果. 对索引列使用OR将造成全表扫描. 注意, 以上规则只针对多个索引列有效. 如果有column没有被索引, 查询效率可能会因为你没有选择OR而降低. 在下面的例子中, LOC_ID 和REGION上都建有索引.

    高效:

    SELECT LOC_ID , LOC_DESC , REGION

    FROM LOCATION

    WHERE LOC_ID = 10

    UNION

    SELECT LOC_ID , LOC_DESC , REGION

    FROM LOCATION

    WHERE REGION = “MELBOURNE”

    低效:

    SELECT LOC_ID , LOC_DESC , REGION

    FROM LOCATION

    WHERE LOC_ID = 10 OR REGION = “MELBOURNE”

    如果你坚持要用OR, 那就需要返回记录最少的索引列写在最前面.

    (25) 用IN来替换OR

    这是一条简单易记的规则,但是实际的执行效果还须检验,在ORACLE8i下,两者的执行路径似乎是相同的. 

    低效:

    SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30

    高效

    SELECT… FROM LOCATION WHERE LOC_IN IN (10,20,30);

    (26) 避免在索引列上使用IS NULL和IS NOT NULL

    避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引.对于单列索引,如果列包 含空值,索引中将不存在此记录. 对于复合索引,如果每个列都为空,索引中同样不存在此记录. 如果至少有一个列不为空,则记录存在于索引中.举例: 如果唯一性索引建立在表的A列和B列上, 并且表中存在一条记录的A,B值为(123,null) , ORACLE将不接受下一条具有相同A,B值(123,null)的记录(插入). 然而如果所有的索引列都为空,ORACLE将认为整个键值为空而空不等于空. 因此你可以插入1000 条具有相同键值的记录,当然它们都是空! 因为空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使ORACLE停用该索引.

    低效: (索引失效)

    SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL;

    高效: (索引有效)

    SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0;

    (27) 总是使用索引的第一个列:

    如果索引是建立在多个列上, 只有在它的第一个列(leading column)被where子句引用时,优化器才会选择使用该索引. 这也是一条简单而重要的规则,当仅引用索引的第二个列时,优化器使用了全表扫描而忽略了索引

    (28) 用UNION-ALL 替换UNION ( 如果有可能的话):

    当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方 式被合并, 然后在输出最终结果前进行排序. 如果用UNION ALL替代UNION, 这样排序就不是必要了. 效率就会因此得到提高. 需要注意的是,UNION ALL 将重复输出两个结果集合中相同记录. 因此各位还是要从业务需求分析使用UNION ALL的可行性. UNION 将对结果集合排序,这个操作会使用到SORT_AREA_SIZE这块内存. 对于这块内存的优化也是相当重要的. 下面的SQL可以用来查询排序的消耗量

    低效:

    SELECT ACCT_NUM, BALANCE_AMT

    FROM DEBIT_TRANSACTIONS

    WHERE TRAN_DATE = '31-DEC-95'

    UNION

    SELECT ACCT_NUM, BALANCE_AMT

    FROM DEBIT_TRANSACTIONS

    WHERE TRAN_DATE = '31-DEC-95'

    高效:

    SELECT ACCT_NUM, BALANCE_AMT

    FROM DEBIT_TRANSACTIONS

    WHERE TRAN_DATE = '31-DEC-95'

    UNION ALL

    SELECT ACCT_NUM, BALANCE_AMT

    FROM DEBIT_TRANSACTIONS

    WHERE TRAN_DATE = '31-DEC-95'

    (29) 用WHERE替代ORDER BY:

    ORDER BY 子句只在两种严格的条件下使用索引.

    ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序.

    ORDER BY中所有的列必须定义为非空.

    WHERE子句使用的索引和ORDER BY子句中所使用的索引不能并列.

    例如:

    表DEPT包含以下列:

    DEPT_CODE PK NOT NULL

    DEPT_DESC NOT NULL

    DEPT_TYPE NULL

    低效: (索引不被使用)

    SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE

    高效: (使用索引)

    SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0

    (30) 避免改变索引列的类型:

    当比较不同数据类型的数据时, ORACLE自动对列进行简单的类型转换.

    假设 EMPNO是一个数值类型的索引列.

    SELECT … FROM EMP WHERE EMPNO = ‘123'

    实际上,经过ORACLE类型转换, 语句转化为:

    SELECT … FROM EMP WHERE EMPNO = TO_NUMBER(‘123')

    幸运的是,类型转换没有发生在索引列上,索引的用途没有被改变.

    现在,假设EMP_TYPE是一个字符类型的索引列.

    SELECT … FROM EMP WHERE EMP_TYPE = 123

    这个语句被ORACLE转换为:

    SELECT … FROM EMP WHERE TO_NUMBER(EMP_TYPE)=123

    因为内部发生的类型转换, 这个索引将不会被用到! 为了避免ORACLE对你的SQL进行隐式的类型转换, 最好把类型转换用显式表现出来. 注意当字符和数值比较时, ORACLE会优先转换数值类型到字符类型

    (31) 需要当心的WHERE子句:

    某些SELECT 语句中的WHERE子句不使用索引. 这里有一些例子.

    在下面的例子里, (1)‘!=' 将不使用索引. 记住, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表中. (2) ‘||'是字符连接函数. 就象其他函数那样, 停用了索引. (3) ‘+'是数学函数. 就象其他数学函数那样, 停用了索引. (4)相同的索引列不能互相比较,这将会启用全表扫描.

    (32) a. 如果检索数据量超过30%的表中记录数.使用索引将没有显著的效率提高.

    b. 在特定情况下, 使用索引也许会比全表扫描慢, 但这是同一个数量级上的区别. 而通常情况下,使用索引比全表扫描要块几倍乃至几千倍!

    (33) 避免使用耗费资源的操作:

    带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL语句会启动SQL引擎

    执行耗费资源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要执行两次排序. 通常, 带有UNION, MINUS , INTERSECT的SQL语句都可以用其他方式重写. 如果你的数据库的SORT_AREA_SIZE调配得好, 使用UNION , MINUS, INTERSECT也是可以考虑的, 毕竟它们的可读性很强

    (34) 优化GROUP BY:

    提高GROUP BY 语句的效率, 可以通过将不需要的记录在GROUP BY 之前过滤掉.下面两个查询返回相同结果但第二个明显就快了许多.

    低效:

    SELECT JOB , AVG(SAL)

    FROM EMP

    GROUP JOB

    HAVING JOB = ‘PRESIDENT'

    OR JOB = ‘MANAGER'

    高效:

    SELECT JOB , AVG(SAL)

    FROM EMP

    WHERE JOB = ‘PRESIDENT'

    OR JOB = ‘MANAGER'

    GROUP JOB


     

    ORACLE查询或删除时指定使用索引的写法

    查询时可以指定使用索引的写法。

    SELECT   /*+ index(TB_ALIAS IX_G_COST3) */
    TB_ALIAS.*
    FROM g_Cost TB_ALIAS
    WHERE Item_Two = 0
       AND Flight_Date >= To_Date('20061201', 'YYYYMMDD')
       AND Flight_Date <= To_Date('20061231', 'YYYYMMDD');

    删除时也可以指定使用索引的写法。

    DELETE   /*+ index(TB_ALIAS IX_G_COST1) */
    FROM g_Cost TB_ALIAS
    WHERE ITEM_NAME = '小时费';

  • 用Popup窗口建无限级Web页菜单

    在Web上使用菜单可以极大地节约页面的空间,同时也比较的符合用户从Windows上继承下来的UI操作体验。在以往的Web页菜单设计中,我们普遍使用div嵌套table的方式来实现菜单,这样的菜单有个最致命的问题就是会被<select>覆盖。

     

    我们为了解决这个问题,有时我们干脆在显示图层菜单的同时隐藏页面上的所有下拉列表框,在菜单消失的时候,再显示他们。这个方法虽然可以解决问题,而其优化过后还可以只隐藏和下拉列表框相交的列表框,但是这些解决方法都不是十分的完美。还有些小问题,这样的菜单定位很困难,因为在<div>显示的时候,用户可以使用鼠标滚轮滚动页面,这样一来是否要让<div>菜单和页面滚动同步呢?如果不要,页面被滚走了,菜单仍显示在一个和自己毫不相关的位置上很是古怪。如果要同步,那么噩梦就来了,因为被滚动的区域不一定就是<body>区域,还可能是一些类似<div style="overflow:auto"><div>的区域,要算出菜单的位置将会非常的麻烦。

    下面将介绍的Popup来实现的Web页菜单将完全解决<div>做为菜单容器时遇到的问题,Popup窗口是IE5.5及以后版本提供的一个新feature。什么是popup呢?简单说popup其实就是一个弹出窗口,它拥有以下特点(MSDN描述):

    ·popup窗口在用户点击它自身之外的任何地方或另一个popup打开的时候会自动关闭;

    ·popup在显示的时候不能获得焦点,所以用户已focused的操作将继续在其父窗口中执行;

    ·组成popup的DHTML可以存储在其父document或其他的document元素中;

    ·popup窗口中不支持文本框一类的编辑框element;

    ·不能选中popup窗口中的元素;

    ·不能在popup窗口中navigate(点击popup中的连接,不能让更新的内容显示到这个popup中);

    ·popup窗口一旦显示就不能移动和resize。

    这里MSDN说的不全,而且有的地方不是很准确,popup窗口还有几个重要的特性。它可以超出浏览器的窗口范围而且也不会被下拉框、flash、IFrame等这些元素遮挡。实际上popup里的内容是可以被选择的,不知道MSDN说的不能选择是啥意思?。关于MSDN说popup不能获得焦点也有点问题,其实是popup里的编辑框类控件不能获得焦点,而其它的非可编辑控件是可以获得焦点的。而且popup显示的时候,IE主窗口不能获得鼠标的onmousewheel事件。

    这样的一些特性,恰好表明了popup窗口非常的适合用来制作弹出菜单,并且由于popup窗口显示的时候,IE窗口内的文档是不能被移动的,这样就不存在context menu的位置同步问题了,因为毕竟popup窗口不能move(move位置需要hide以后在新的位置上重show),这个问题还比较讨厌。

    使用popup窗口制作无限级别的菜单,有两个问题要解决:一个是要能在一个IE中显示多个Popup窗口,二是要能把窗口中的一些事件俘获并执行我们脚本过程。MSDN在描述popup窗口特性时,第一条就说了只要有另一个popup窗口开启,先前显示的popup窗口就会自动关闭。这下怎么办呢?不过既然都说了要实现无限级的菜单了,办法还是有的。对于popup,使用方式其实是很简单的,他一共就只包含了两个方法:hide()和show(...),和两个属性:document和isOpen。虽然在IE中我们连续的调用n次window.createPopup().show(...)只能出来一个popup窗口被显示,可是我们可以调用popup.document.parentWindow的createPopup方法,它产生的popup窗口在显示的时候就不会关闭前面已显示的popup窗口,并且对于新的popup用这个方法可以继续开启child popup。这个问题再研究下去,会发现IE实现popup的一些怪异的地方(当然这些对于我们实现这个菜单关系不太大,只是觉得混乱)。

    比如我们在一个IE窗口中,var popup = window.createPopup(); var win = popup.document.parentWindow; 我们会发现 window != win,对于多个popup可以共存,这个不相等还能理解,但是当我们调用win.resizeTo(...)的时候,我们发现父IE窗口被resize了。同样我们在popup中select all,结果也是父IE窗口里的内容被全选了@_@...URl收藏 http://www.qqread.com/javascript/d321885030.html进入讨论组讨论。

Copyright SDT, 2006-2007. All rights reserved.