精华内容
下载资源
问答
  • VB - 数据文件(顺序文件

    万次阅读 2011-11-03 22:36:24
    1. 打开文件(Open) Open 文件名 [For模式][Access 存取类型][锁定]As [#]文件号[Len=记录长度]  说明: (1)文件名; (2) 模式用于指定文件访问的方式,包括:  Append——从文件末尾添加 Binary——二进制...

    1. 打开文件(Open)

    Open 文件名 [For模式][Access 存取类型][锁定]As [#]文件号[Len=记录长度]

           说明:

    (1)文件名;

    (2) 模式用于指定文件访问的方式,包括:
               Append——从文件末尾添加             Binary——二进制文件
               Input——顺序输入(输入给自己,从txt中取出)                            Output——顺序输出(输出到txt中)
               Random——随机存取方式

    (3)文件号(或称文件缓冲区)

    (4)存取类型:访问文件的类型,为Read(只读)、Write(只写)、Read Write(读写)

    (5)锁定:限制其他用户或其他进程对文件进行读写操作

                           Shared(共享)、LockRead(禁止读)、Lock Write(禁止写)、

                              Lock Read Write(禁止读写)

    (6)Len:用来指定每个记录的长度(字节数)

          示例:    Open"d:\cj1.dat" For  Output As  #1

    2. 关闭文件(Close)

             打开的文件使用完后必须关闭。

             关闭文件的语句格式:
               Close[#] 文件号1[,[#] 文件号2…] ]

             示例:

               Close#1

     1. Write语句 
       格式:Write#文件号 [,表达式表]
        功能:将表达式的值写到与文件号相关的顺序文件中
        每个Write语句向顺序文件写入一个记录(不定长),它会自动地用逗号分开每个表达式的值。给字符串加上双引号

             在最后一个字符写入后,插入一个回车换行符(Chr(13) + Chr(10)),以此作为记录结束的标记。

             示例:Write#1, "Good Afternoon", 1998


    Private Sub CommandButton1_Click()
        Dim num As String * 6, name As String * 8, score As Integer
        num = TextBox1.Text
        name = TextBox2.Text
        score = Val(TextBox3.Text)
        Write #1, num, name, score
        TextBox1.Text = ""
        TextBox2.Text = ""
        TextBox3.Text = ""
        TextBox1.SetFocus
    End Sub
    
    Private Sub CommandButton2_Click()
        Close #1
        End
    End Sub
    
    Private Sub UserForm_Initialize()
        Open ThisWorkbook.Path & "\1.txt" For Output As #1
    End Sub
    
    运行结果~

    读取数据,用For...Next 语句

    Sub 的开发商的()
        Dim n As String, m As String, s As Integer
        Open ThisWorkbook.Path & "\1.txt" For Input As #1
        For i = 1 To 5
            Input #1, n, m, s
            Cells(i, 1) = n
            Cells(i, 2) = m
            Cells(i, 3) = s
        Next
        Close #1
    End Sub

     2. Print语句 

    格式:Print  #文件号[,表达式表]
            作用与Write一样。将一个或多个表达式的值写到与文件号相关的顺序文件中。其输出数据格式与Print方法在窗体上输出格式相似。

               示例:
                Print  #1, num, name, score              ‘对应按区格式
                Print  #1, num;name;score          ‘对应紧凑格式


    先用Input方式打开文件,然后采用Input或LineInput语句从文件中读出数据。通常,Input用来读出Write写入的记录内容,而Line Input用来读出Print写入的记录内容

    1.Input语句 
        一般格式:Input#文件号,变量名表
          功能:从指定文件中读出一个记录。变量个数和类型应该与要读取的记录所存储的数据一致。
           打开文件时,文件指针指向文件中的第1个记录,以后每读取一个记录,指针就向前推进一次。如果要重新从文件的开头读数据,则先关闭文件后打开

    距离:

    Sub sj()
        Open ThisWorkbook.Path & "\data1.txt" For Output As #1
        a = 123: b$ = "ABCD"    '在同一行赋值,用“:”
        Write #1, a, b$
        Close #1
        Open ThisWorkbook.Path & "\data1.txt" For Input As #1
        Input #1, c, d$
        Close #1
        Debug.Print c, d$
    End Sub


    Sub dfjslkdf()
        Open ThisWorkbook.Path & "\num2.txt" For Append As #1
        For i = 51 To 200
            If i Mod 7 = 0 Then Write #1, i
        Next
        Close #1
    End Sub
    
    Sub dfhdfdffdfdfdk()
        k = 0
        Open ThisWorkbook.Path & "\num2.txt" For Input As #1
        Do While Not EOF(1)
            Input #1, x
            Debug.Print x,
            k = k + 1
            If k Mod 4 = 0 Then Debug.Print
        Loop
    End Sub

    Debug.Print i    一行一行的输出

    Debug.Print i,    在一行输出,中间空很多的空格,具有一定的格式

    Debug.Print i;    在一行输出,中间空很少的空格,具有一定的格式

    可以加入If i Mod 2 = 0 Then Debug.Print    可以进行换行


    Print也有相似的用法:

    从TXT中读取数据,数据中间可以是空格、半角逗号

    Sub dhfkd()
        k = 0
        Dim arr(1 To 1100) As Variant
        Open ThisWorkbook.Path & "\num2.txt" For Input As #1
        Do While Not EOF(1)        'EOF(1)用来判断#1是否读到头了,到头返回TRUE
            Input #1, x           '读取一个数据
            k = k + 1
            arr(k) = x            '将读取的数据存在一个数组中
        Loop
        k = 0
        For i = 1 To 10
            For j = 1 To 110
                k = k + 1
                Cells(j, i) = arr(k)
            Next
        Next
        Close #1
    End Sub

    2.Line Input语句 

    格式:LineInput  #文件号,字符型变量
    功能:从打开的顺序文件中读出一个记录,即一行信息  

    用Line input来读取由Print写入的数据,Line Input读取一整行的数据~

    Sub djhfdljf()
        Open ThisWorkbook.Path & "\mytxt.txt" For Output As #1
        a = 123: b$ = "SBCD"
        Print #1, a, b$
        Print #1, a; b$
        Close #1
        Open ThisWorkbook.Path & "\mytxt.txt" For Input As #1
        Line Input #1, x$
        Debug.Print x$
        Line Input #1, x$
        Debug.Print x$
        Close #1
    End Sub


    3.Input函数           

    格式:Input(字符数,#文件号)
        功能:从文件中读取指定字符数的字符
        示例:A$=Input(20, #1)
            顺序文件的缺点是不能快速地存取所需的数据,也不容易进行数据的插入、删除和修改等工作,因此对于经常要修改数据或取出文件中个别数据,均不适合使用,但对于数据变化不大,每次使用时又需要从头往后顺序地进行读写,它还是不失为一种好的文件结构

    展开全文
  • )打开和关闭文件 1、顺序文件 打开顺序文件,我们可以使用Open语句。它的格式如下: Open pathname For [Input |Output |Append] As [#]filenumber [Len = buffersize] 说明: (1)参数pathname 表示要打开的

    (一)打开和关闭文件  
     
      1顺序文件  
     
      打开顺序文件,我们可以使用Open语句。它的格式如下:  
      Open   pathname   For   [Input   |Output   |Append]   As   [#]filenumber   [Len   =   buffersize]    
     
      说明:  
     
      (1)参数pathname   表示要打开的文件名,文件名可以包含有驱动器和目录  
     
      (2Input   Output   Append用于设置顺序文件的打开方式。其中,Input表示从打开的文件中读取数据。以这种方式打开文件时,文件必须存在,否则会产生错误。Output表示向打开的文件中写入数据。以这种方式打开文件时,文件中原有的数据将被覆盖,新的数据将从文件开始写入。如果文件不存在,则创建一个新文件。Append表示向打开的文件中添加数据。以这种方式打开时,文件中原有的数据将被保留,新的数据将从文件为开始添加。如果文件不存在,则创建一个新文件。  
     
      (3As[#]filenumber   子句用于为打开的文件指定文件号.对文件进行读写操作时,要用文件号表示该文件.文件号是介于1~511之间的整数,既可以是数字,又可以是变量.也可以省略不用.  
     
      (4)当在文件与程序之间拷贝数据时,Len=buffersize子句指定缓冲区的字符数.  
     
      例如:  
      Open   App.Path   +   "/test.dat"   For   Output   As   1  
      Open   App.Path   +   "/test.dat"   For   Output   As   1    
     
      这两句代码在当前应用程序所在目录下创建了一个名为test.dat的文本文件,分配文件号为1.  
      Open   App.Path   +   "/test.dat"   For   Input   As   [#]filenumber    
     
      这条语句是从文本文件中读取数据.  
      Open   App.Path   +   "/test.dat"   For   Append   As   [#]filenumber    
     
      这条语句则是像文本文件中添加数据  
     
      2随机文件  
     
      操作随机文件之前,首先必须定义用于保存数据项的记录类型.该记录是用户自定义数据类型,他们是随机文件中存储数据的基本结构.例如:  
      Type   Student  
     
     No   As   Integer  
     
     Name   As   String   *   20  
     
     age   As   Integer  
      End   Type  
      Dim   Stud   As   Student   ‘
    定义一个可以存放学生材料的变量    
     
      随机文件中,所有的数据都将保存到若干个结构为Student类型的记录中,   而从随机文件中读出的数据则可以存放到变量Stud.  
     
      之后我们就可以打开并读写文件了.下面是打开随机文件的语法格式:  
      Open   filename   For   Random   as   [#]filenumber   Len   =   Reclength    
     
      说明:  
     
      (1)参数filename   filenumber   分别表示文件名或文件号.  
     
      (2)关键字Random   表示打开的是随机文件  
     
      (3)Len子句用于设置记录长度,长度由参数Reclength指定.Reclength的值必须大于0,而且必须与定义的记录结构的长度一致.计算记录长度的方法是将记录结构中每个元素的长度相加.例如前面声明的Student的长度应该是2+20+2=24字节.  
     
      打开一个记录类型为Student   的随机文件的方法是:  
      Open   "c:/Student.txt   "   For   Random   As   #1   Len   =   25    
     
      3二进制文件  
     
      打开二进制文件的语法格式如下:  
      Open   pathname   For   Binary   As   [#]filenumber    
     
      说明:

    (1)   参数filename   filenumber   分别表示文件名或文件号.  
     
      (2)关键字Binary   表示打开的是二进制文件  
     
      (3)对于二进制文件,不能指定字节长度.每个打开的二进制文件都有一个自己的指针,文件指针是一个数字值,指向下一次读写操作的文件中的位置.二进制文件中的每个位置对应一个数据字节,因此,n个字节的文件,就有1n个位置.  
     
      我们可以用Seek()函数返回当前的文件指针位置(即下一个要读写的字节   );Loc()函数返回上一次读写的字节位置,除非用Seek语句移动了指针,Loc()返回值总比Seek()的小1.我们来看下面的例子:  
      Open   “student.txt”   for   Binary   as   #1    
     
      该语句用二进制的方式打开了student.txt文件.

    (二)读文件  
     
      1顺序文件  
     
      顺序文件的读取有三种方式:  
     
      (1Line   Input   #   语句  
     
      该语句从打开的顺序文件中读取一行数据。这里的一行指的是从当前指针位置开始到回车符或回车换行符之间的所有数据。Line   Input   #   语句的语法格式如下:  
      Line   Input   #  
    文件号,变量号    
     
      说明:文件号是打开文件时所用的文件号;变量号使用来存放读出数据的一个或多个变量,如果有多个变量,中间用空格分割开。Input#   语句为参数列表中的每一个变量读取文件的一个域,并将读出的域存入变量中。该语句只能顺序的从第一个域开始,直到读取想要的域。  
     
      请看下面代码:  
      Dim   strLine   As   String  
      Open   "c:/vb/test.txt"   For   Input   As   #1  
      Do   Until   EOF(1)  
     
     Line   Input   #1,   strLine  
     
     text1.Text   =   text1.Text   +   strLine   +   Chr(13)   +   Chr(10)  
      Loop  
      Close   #1    
     
      此段代码逐行读取一个文件到文本框中。  
     
      (2Input函数  
     
      此函数可以从顺序文件中一次读取指定长度的字符串。具体地说,就是从文件的当前位置开始,读取指定个数的字符,然后将他们返回。Input函数可以读取包括换行符,回车符,空格符等在内的各种字符。下面是它的语法格式:  
     
      变量   =   Input(串长度,文件号)  
     
      例如,要从一个打开文件中读取12个字符并复制到变量file中,我们可以这样写:  
      file   =   Input
    12filenum    
     
      如果要将整个文件复制到变量,请使用InputB函数将字节从文件复制到变量。由于InputB函数返回一个ASCII字符串,因此,必须用StrCopy函数将ASCII字符串转换为Unicode字符串。代码如下:  
      file   =   StrCopy  
    Input   LOFfilenanum),filenum),vbUnicode  
     
      (3Input   #   语句  
     
      Input   #语句可以从文件中同时向多个变量内读入数据,而且读入的数据可以是不同类型的。  
     
       
     
      下面使它的语法格式:  
      Input   #  
    文件号,变量列表    
     
      例如,我们要在文件student.txt中写入数据,下面是代码:
      Open   "student.txt"   For   Output   As   #filenum  
      Write   #filenum,   "
    张三",   "初一年级",   14  
      Write   #filenum,   "
    李四",   "职业高中",   18  
       
      Dim   name   As   String,   nianji   As   String,   age   As   Integer  
      Dim   name1   As   String,   nianji1   As   String,   age1   As   Integer  
      Open   "student.txt"   For   Input   As   #filenum  
      Input   #filenum,   name,   nianji,   age  
      Input   #filenum,   name1,   nianji1,   age1  
      Close   #filenum    
     
      执行结果:  
      name=”
    张三”   ,nianji   =   “初一年级”   ,age   =14    
      name=”
    李四”   ,nianji   =   “职业高中”   ,age   =18      
     
      2随机文件  
     
      读取随机文件是可以使用Get   #   语句,数据从文件的一个指定记录中读出后,存入一个用户自定义的变量中.  
     
      语法格式:   Get   #   FileNum   ,[RecNum],UserType  
     
      说明:  
     
      (1)FileNum   是要打开的文件号;RecNum是要读取的记录号,若省略,则读取下一个记录  
     
      (2)UserType   是一个用来存放读出数据的用户自定义的数据类型变量.  
     
      下面是一个例子:  
      Get   #   1,5,Student      
     
      该语句读取文件号为1的文件中的第5条记录.  
     
      3二进制文件  
     
      读写二进制文件的方法和读写随机文件的方法基本相同,下面是相关的语句格式及其说明:  
     
      格式:   Get   [#]fileNumber   ,[Pos],   Var  
     
      功能:   用二进制方式,从文件的中指定的位置开始读取,所给变量长度的数据  
     
      说明:  
     
      (1)FileNumber是以二进制方式打开的文件号.  
     
      (2)Pos用来指定读写操作发生时的字节位置,若省略,则使用当前文件指针位置.  
     
      (3)Var是用来存放读出的数据的变量.该语句会自动根据var变量包含的字节长度读取适当的文件,如果Var是一个可变长度的字符串变量,则传送的字节数等于Var中目前的字节数.对于文件长度的判断我们可以使用Lof()函数,Eof()函数检查文件的结尾位置.  
     
      下面的代码复制studert.txt文件到student1.txt文件中  
      Dim   ar   As   String   *   1,   i   As   Integer  
      Open   "c:/student.txt"   For   Binary   As   #1  
      Open   "c:/student2.txt"   For   Binary   As   #2  
      For   i   =   1   To   LOF(1)  
     
     Get   #1,   ,   ar  
     
     Put   #2,   ,   ar  
      Next   i  
     Close   #1,   #2

    (三)写文件  
     
      1   顺序文件  
     
      写顺序文件我们可以用Write   #   Print   #语句向一个已经打开的文件中写入数据.  
     
      下面是他们的格式和说明:  
     
      Print   #   的语法格式:  
     
      Print   #   文件号,变量列表  
     
      例如,将文本框中的文本写到文件中,代码如下:  
      Open   "file.txt"   For   Output   As   #filenum  
      Input   #filenum,   text1.text    
     
      Write   #   语句的语法格式:  
      Write   #  
    文件号,变量列表    
     
      说明:Write   #   语句写入的信息便于以后用Input   #语句来读取数据,因为Write   #语句自动将写入到文件中的信息用逗号分开,并为字符串数据加上双引号.例如:  
      Open   "student.txt"   For   Output   As   #filenum  
      Write   #filenum,   "
    张三",   "初一年级",   14  
      Write   #filenum,   "
    李四",   "职业高中",   18    
     
      2   随机文件  
     
      向随机文件中写入数据,使用Put #语句.语法格式如下:  
      Put   [#]   FileNum   ,[RecNum],UserType    
     
      说明:  
     
      (1)   FileNum   是要打开的文件号;RecNum是要写入的记录号,若省略,则再上一次用Get   Put语句所读写过的记录的后一条记录中写入,如果没有执行过Get   Put语句,就从第一条记录开始  
     
      (2)UserType   是包含要写入数据的用户自定义的数据类型变量.例如:我们向前面的student.txt文件中的第5个记录写入数据,可用这些语句:  
      stud.No   =   0301  
      stud.Name   =   “
    王武”  
      stud.Age   =20  
      Put   #1   ,5,stud    
     
      如果要插入的数据不只一两条的话,首先要确定文件和每条记录的长度,这样就可以计算出文件中究竟有多少条记录.我们可以用Lof()函数返回文件的长度,Len()函数返回每个记录的长度,计算文件中的记录个数可以用文件的长度除以给个记录的长度.示例如下:  
      Nextrec=   (Lof(1)/Len(UserType))+1  
      Put   #1,Nextrec,UserType    
     
      3二进制文件  
     
      下面是以二进制方式写入文件的语句格式及其说明:  
     
      格式:  
      Put   [#]fileNumber   ,[Pos],   Var    
     
      功能:   用二进制方式,从文件的中指定的位置开始写入,所给变量长度的数据  
     
      说明:  
     
      (1)FileNumber是以二进制方式打开的文件号.  
     
      (2)Pos用来指定写操作发生时的字节位置,若省略,则使用当前文件指针位置.  
     
      (3)Var是用来存放写入的数据的变量.该语句会自动根据var变量包含的字节长度写入文件,如果Var是一个可变长度的字符串变量,则传送的字节数等于Var中目前的字节数.  
     
      使用方法可参考二进制文件的读操作。

    展开全文
  • 基于CICS的COBOL程序顺序文件处理

    千次阅读 2011-10-29 22:09:52
    CICS顺序文件处理中,使用浏览(browse)概念来进行操作。因而这些操作包括开启浏览,执行文件记录读取(正向/反向),关闭浏览等。 由于是CICS命令,在COBOL中使用时,必须包含在EXEC CICS语句对中。 浏览可以...

    CICS顺序文件处理中,使用浏览(browse)概念来进行操作。因而这些操作包括开启浏览,执行文件记录读取(正向/反向),关闭浏览等。

    由于是CICS命令,在COBOL中使用时,必须包含在EXEC CICS语句对中。

    浏览可以用于访问VSAM文件,包括PDS,ESDS, KSDS和RSDS。

    1. 开启浏览(Start Browse)命令 STARTBR,命令格式:

    STARTBR FILE(<file>)        FCT中的文件名
            RIDFIEILD(<data>)   定义起始位置,可以是索引键值(Key),RRN或RBA
            [RRN | RBA]         指示起始位置表述是RRN(Relative Record Number用于RRDS)还是RBA
                                (Relataive Byte Addres用于ESDS或KSDS)
            [GTEQ | EQUAL]      起始于第一个键值大于等于或严格等于指定索引键值的记录
                                (故只对RIDFIELD为索引键有效)
            [GENERIC]           只对KSDS有效,指示仅部分RIDFIELD指定的键值被使用
            [KEYLENGTH(data | literal)]  和GENERIC共用,用于指示键长。二进制半字长或字面值
            [RESP(<response-code>)]      返回条件值
    

    如果找到没有匹配记录,则返回NOTFND条件值,否则返回NORMAL条件值。

    2. 顺序读取(前向READNEXT / 反向READPREV),命令格式:

    { READNEXT | READPREV } FILE(<file>)   FCT中的文件名
                            INTO(<data>)   读出数据的存放位置
                            RIDFLD(<data>) 位置指针,和开启浏览相承,会随着读取而相应前进或后退;
                                           用户也可在读取之前指定之从而设定读取位置
                            [RRN | RBA]    起始位置表述内容,类似于开启浏览
                            [KEYLENGTH(~)] 类似于开启浏览
    

    注意:使用GENERIC开启的浏览,无法使用反向阅读。


    3. 关闭浏览命令ENDBR,命令格式:

    ENDBR  FILE(<file>)     FCT中的文件名
    

    4. 重置浏览命令RESETBR,命令格式:

    RESETBR FILE(<file>)
            RIDFLD(<data>)
            [RRN | RBA]
            [GTEQ | EQUAL]
            [GENERIC]
            [KEYLENGTH(~)]
    

    其参数和开启命令类似,起作用是重新开始一个已经打开的浏览


    返回条键值表:

    条件值原因
    FILENOTFOUND文件没有在FCT中定义
    ENDFILE到达文件边缘,没有记录可读
    ILLOGICVSAM错误
    INVREQ浏览命令错误,通常是没有在读取之前启动浏览
    IOERR底层输入输出错误
    NOTFND命令中指定的记录没有找到
    NOTOPEN文件没有打开(FCT中配置属性问题)

    展开全文
  • 如何编写一个高效的sql语句

    千次阅读 2017-06-16 08:38:48
    一. 序言 数据库的性能问题,一直以来都是困扰各个事业部的大问题。在性能问题中SQL语句的编写又是重中之...在ORACLE RDBMS SERVER软件的内部,对于SQL语句的执行有一个优化器(OPTIMIZER)对SQL语句的执行进行优化。

     

    一.    序言

    数据库的性能问题,一直以来都是困扰各个事业部的大问题。在性能问题中SQL语句的编写又是重中之重。因此,为提高各个事业部相应产品的执行效率,提高软件的性能,实现从功能要求到性能要求的转变,特编写此专题文章。

    二.    SQL的优化器执行分析

    在ORACLE RDBMS SERVER软件的内部,对于SQL语句的执行有一个优化器(OPTIMIZER)对SQL语句的执行进行优化。在我们使用后面介绍的工具对SQL的执行路径进行查看的时候,系统显示出来的是由优化器给出的执行路径的解释方案,如果对优化器的解释方案不了解的话,就无法针对出现的问题进行SQL语句的调整。现把ORACLE8提供的优化器的执行解释方案公布如下。

    1.            如何看SQL解释方案

    Execution Plan

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

    1  SELECT STATEMENT Optimizer=CHOOSE (Cost=94Card=1)

    2   SORT (AGGREGATE)

    3    COUNT (STOPKEY)

    4      INDEX (FULL SCAN) OF 'PK_TBI_TM' (UNIQUE)(Cost=94 Car

             d=27164)

                         (图1)

    图1为ORACLE对语句“select count(*) from tbi_tmwhere rownum<10”给出的一个执行的解释方案,那我们该如何看这个方案呢?我们在看这个执行方案的时候要遵循一个原则“由里到外,由高到低”,同时“由里到外”不能违反“由高到低”的原则。因此上述的语句的执行步骤顺序为:432;假设存在一个步骤5的话,而且它的层次同3一致,那么,上述语句的执行步骤顺序就会改为:4352。在图1中还给出了执行了何种操作(例如:INDEX(FULL SCAN),COUNT (STOPKEY)等,具体的说明在下面进行解释),同时在最后还给出了执行的代价(COST)。

    2.            SQL解释方案介绍

    2.1.          操作说明

    系统中的全部操作可分为行操作或集(SET)操作。二者之间的比较可以对比如下:

    行操作

    集操作

    一次执行一行

    在行的结果集上执行

    如果不涉及集操作将在FETCH级上操作

    当光标打开时,在EXECUTE级上执行

    在取最后一行之前,用户可以看到第一次的结果

    用户不能看到第一次的结果,直到所有的行被取出和处理完

    示例:全表扫描

    示例:使用group by子句的全表扫描

     

    对于行和集操作的分类如下(暂时列到ORACLE 8):

    行操作

    集操作

    And-equal,Bitmap,Concatenation,Count stopkey,Filter,For update,Index full scan,Index range scan,Index unique scan,Intersection,Merge join,Nested loops,Outer join,Projection,Sequence,Table access by rowid,Table access cluster,Table access full,Table access hash,Union,Union-all

    Connect by,Count,Hash join,Minus,Remote, Sort aggregate,Sort group by,Sort join,Sort order by,Sort unique,View

    2.2.          具体操作解释

    在上述的操作中有许多我们平时很少用到,因此就不一一介绍了,只介绍日常常用的一些操作:

    2.2.1.         约定

    Table_name

    Column_name

    Index_type

    Company

     

     

     

    Company_id

    U_ind

     

    City

    Ind

     

    State

    Ind

     

    Parent_company_id

    Ind

    Competitor

     

     

     

    Company_id

    U_ind

     

    Product_id

    U_ind

    Sales

     

     

     

    Company_id

    U_ind

     

    Period_id

    U_ind

     

    2.2.2.         AND-EQUAL

    说明:用来合并由索引返回的值的排序列表。AND-EQUAL用于非唯一索引的合并和唯一索引的范围扫描。

    例子:selectname,city,state from company where city=’Roanoke’ and state=’VA’

    2.2.3.         CONCATENATION

    说明:用来执行结果集的unionall操作

    例子:selectname,city,state from company where state=’TX’ and city in (‘Houston’,’Austin’,’Dallas’);

    该例子最终可以该写成:selectname ,city,state from company where (state=’TX’ and city=’Houston’) or (state=’TX’and city=’Austin’ ) or (state=’TX’ and city=’Dallas’);

    备注:有时候在语句比较复杂时,Oracle可能不会使用CONCATENATION操作,而是使用部分索引的范围扫描(Range Scan)。如果要强制使用CONCATENATION操作,就把语句写成最终的样子。

    2.2.4.         COUNT

    说明:当使用伪列(Pseudo-column),并且指定RowNum的最大值时,执行Count(计数)。Count从它的子操作接收行并且增大RowNum的计数。

    例子:selectname,state,rownum from company where city>’Roanoke’

    2.2.5.         COUNT STOPKEY

    说明:当使用限定计数的RowNum伪列时,执行COUNT STOPKEY。它从先前的操作接收行并且增加计数,如果计数达到了临界值,就产生一个“NoMore Rows”条件,结束查询并把结果返回给用户。

    例子:selectname,city,state,rownum from company where city>’Roanoke’ and rownum<10;

    2.2.6.         FILETER

    说明:使用在当没有索引可以用来帮助评估时,FILTER执行一个where子句条件。当FILTER在一个解释方案里显示时,通常显示的是索引丢失或者存在的索引不能用的结果。

    2.2.7.         FOR UPDATE

    说明:为所有能从select语句回复的行级别(row level)上加锁。

    例子:select namefrom company where city>’Roanoke’ for update of name;

    2.2.8.         HASH JOIN

    说明:它是行操作和集操作的混合。它在内存中创建其中一个表的位图,然后利用哈希(HASH)功能在第二个表里定位联结行,通过HASH JOIN(哈希联结)将表联结起来。

    例子:selectcompany.name from company,sales where company.company_id=sales.company_id andsales.period_id=3 and sales.sales_total>1000;

    注意:在这个例子中,sales表作为联结表被读到内存中,然后同company表中的记录进行逐行比较。能够使用到hash join的条件为在联结的表中,一张表比其他的联结表小的多,并且这些记录能够全部被读到内存中去,那么系统就会使用hash join而不是使用nested loops来进行连接。有时即使为联结提供了一个索引,hash join也许比nested loops联结跟可取。

    2.2.9.         INDEX RANGE SCAN

    说明:它从索引里选择一定范围的值,索引既可以是唯一的也可以是复合的。当遇到下列条件时,使用它:

    l  使用范围操作(如>or<)

    l  使用between子句

    l  使用有通配符的查找字符串(如:’b%’)

    l  只使用复合索引的一部分

    例子:selectname,city,state from company where city>’Roanoke’

    注意:它的效率与两个因素有关:选择范围内的关键值的数目以及索引的条件,当关键数目越多,查找时间越长;分段越多,查找时间越长。

    INDEX UNIQUE SCAN

    说明:它从唯一索引中选择,是从已知字段里选择一行的最有效的方法。

    例子:selectname,city,state from company where company_id=12345

    2.2.10.      MERGE JOIN

    说明:它通过合并每个表中已排序的记录列表去联结数据表。它主要是针对大型批处理操作,但是对事务处理可能是无效的。当ORACLE实施联结而又不能使用索引时,就使用merge join。

    例子:selectcompany.name from company ,sales where company.company_id+0=sales.company_id+0and sales.period_id=3 and sales.sales_total>1000

    注意:需要值得注意的是它是针对集操作。对于它的执行计划,在执行完一个全表扫描之后还要进行一个sort join的排序操作,然后再进行merge join操作。

    2.2.11.      NESTED LOOPS

    说明:在进行多表的联结时,如果有一个联结的列被索引过的时候,那么nested loops将起作用。

    例子:selectcompany.name from company ,sales where company.company_id=sales.company_id andsales.period_id=3 and sales.sales_total>1000

    注意:

    l  在使用nested loops的时候,查询的驱动表的选择是很重要的,关于这点,这下面会作专题讨论。原则是如果是rule_based的情况下,驱动表将选择from语句的最后一个,如果是cost_based的情况下,驱动表的选择间考虑表的大小和索引的选择性。

    l  在进行nested loops的操作时,首先作的是驱动表的全表扫描,然后才使用索引的扫描,然后才进行nestedloops操作。

    2.2.12.      OUTER JOIN

    说明:它是nestedloops、hash join、merge join操作的一个选项。它死来自驱动表的行能够返回到调用查询,虽然在联结数据表里没有发现任何匹配的行。

    例子:selectcompany.name from company ,sales where company.company_id=sales.company_id(+)and sales.period_id=3 and sales.sales_total>1000

    2.2.13.      SEQUENCE

    说明:当通过nextval和currval来访问sequence时,使用sequence操作。

    例子:selectseq_tbi_tm.nextval from dual;

    2.2.14.      SORT AGGREGATE

    说明:每当对数据集的组操作功能在sql语句中出现但是没有groupby子句时,SORTAGGREGATE(聚集排序)就用来给结果排序和聚集。这些组函数包括:max、min、count、sum、avg

    例子:selectsum(sales_total) from sales;

    2.2.15.      SORT GROUP BY

    说明:在数据集中实现分组功能

    例子:selectzip,count(*)from company group by zip;

    2.2.16.      SORT JOIN

    说明:把用于MERGEJOIN操作的一个记录集排序,同mergejoin是同步出现的。

    例子:selectcompany.name from company ,sales where company.company_id+0=sales.company_id+0and sales.period_id=3 and sales.sales_total>1000

    2.2.17.      SORT ORDER BY

    说明:它用于给结果集排序,但是不去除重复记录。

    例子:select namefrom company order by name;

    2.2.18.      SORT UNIQUE

    说明:在由minus、intersection和union操作处理前,它用于给结果集排序并将重复记录去除。

    例子:selectcompany_id from company minus select company_id from compeitor;

    2.2.19.      TABLE ACCESS BY ROWID

    说明:基于所提供Rowid的操作,它从一个表返回一条记录。这是从一个表返回记录的最快的方法。

    例子:select namefrom company where company_id=12345 and active_flag=’Y’;

    2.2.20.      TABLE ACCESS FULL

    说明:当没有为行查找提供Rowid时,oracle将扫描给定表里的每一块,直到读完所有行。

    例子:select*from company;

    2.2.21.      UNION

    说明:它从两个或者跟多个查询结果返回行的单个集。为了执行这个操作,Oracle首先根据Select语句过滤所有的行,给它们排序,然后实行Union Merge。在Union操作期间,包含了Union all操作。

    例子:selectcompany_id from company union select company_id from competitor;

    注意:如果一个操作不考虑去除重复记录的话,请使用union all,它的执行效率比union高。

    三.    编写高效的SQL:

    在Oracle系统的性能提升过程中,SQL语句的优化的效果是最明显的。因此,编写高效的SQL语句对整个系统性能的提高是应用中效果最明显的,同时也是代价最低的。

    一个高效的SQL语句基本上都是要利用到索引的,因此我们在谈SQL语句的同时也介绍一下索引。并且,任何语句都同回滚段都分不开,因此也会介绍一下回滚段的情况以及使用。

    1.            什么是索引

    1.1.          索引定义

    索引本身也是一个数据库对象。对于在表的索引列上的每一值将包含一项(ENTRY),为行提供直接的快速存取。索引的存储参数的取值和使用同表的存储参数的使用一致。

    1.2.          索引的组织存储形式

    在Oracle系统中,索引的数据存储是以B+树的形式存在的。

           需要值得注意是,在索引的数据项发生删除的时候,释放出来的空闲空间无法再次使用。

           如果对索引数据发生频繁的update或者删除的时候,会导致索引失去平衡,或者导致索引的层次增加,会导致索引停滞(Index Stagnation)现象的出现。为解决该问题,可以考虑重建索引。重建索引可以使用Alter index ….Rebulid语句来实现,该功能可以使索引再次平衡,同时也可以对索引的存储地点以及存储策略进行修改。

           从Oracle 8开始,索引的类型增加了两种,一为位图索引(Bitmap Index)主要针对重复值比较多的列而创建的索引,对它的逻辑操作的效果比较好;一为反向索引(Reverse Index)主要是为尽量保持索引的平衡而考虑创建,对该索引的查询只有使用“=”才起作用,而对于范围内的查询(Range Scan)不起作用。

           对于数据比较多的表创建索引的时候,从考虑效率角度出发,在创建索引的时候使用No Logging的参数来提高效率。该参数在创建索引的时候不产生重作日志,可以有效的提高效率,加快索引的产生。

    1.3.          使用索引的优缺点

    在下列情况下ORACLE可利用索引改进性能:按指定的索引列的值查找行,按索引列的顺序存取表。然而,索引虽然可以加快查询的速度,但是它可减慢INSERT、DELETE和UPDATE命令的速度,由于这些操作要影响索引列的值,ORACLE必须对索引数据和表数据进行维护。

    1.4.          创建索引的限制

    一个索引最多可包含16列(到Oracle 8开始为32列),索引项为每一列的数据值的连串,按指定的列的顺序连串。这一顺序对ORACLE如何使用该索引非常重要。ORACLE在一张表上可建立多个索引,索引的数目没有限制。但是应该注意增加索引会增加维护表所需的处理时间。建议只有当要索引的数据在表中所占的数据量,少于总数据量的15%时,使用索引才会提高查询的速度,否则对表的全表扫描的速度还比使用索引的速度快。

    1.5.          创建索引遵循的原则

    对于索引列的选择遵从下列的准则:

    u  经常用于WHERE子句中使用的列考虑作索引的列。

    u  经常用于SQL语句中连结表的列考虑作为索引的列。

    u  在Cost_based的优化方式下,对于复合索引的主列的选择显的尤为重要。它的选择可以遵循以下原则:在Where条件中频繁使用的列为主列;对于数据最有选择性的列为主列。

    u  一个索引列要具有好的选择性。一个索引的选择性(Selectivity)是对具有相同值的表中的百分比。一个索引的选择性好,就是很少行有相同值。可以通过用具有不同索引值的数目除表中的行数来决定索引的可选择性。可以用ANALYZE命令获取这些值。用这种方法计算的可选择性应该解释为百分比。

    u  不要将具有很少不同值的列作为索引列。这样的列具有很差的选择性,并且不能优化性能,除非频繁选择的值比其他列值来更少出现。例如:在表中如果存在以YES或NO为值的列,那么尽量不要用该列作为索引列,因为用此列作为索引不会提高系统的性能,但是如果在表中YES的值很少出现,而在运用中又经常以YES值为查询,则以该列为索引可能会改进系统的性能。从Oracle 8开始可以考虑创建Bitmap Index来解决一些问题。

    u  不要将频繁修改的列作为索引列。因为修改索引列的UPDATE语句和修改索引表的INSERT和DELETE语句将比没有索引要用更多的时间。这样的语句必须修改索引中的数据,还要修改表中的数据。

    u  不要将只出现在带函数或操作符的WHERE子句中的列作为索引列。使用带索引列的函数(不是MIN或MAX函数)或操作符的WHERE语句并不使用索引的存取路径。

    u 在大量并发INSERT、UPDATE和DELETE语句存取父表和子表的情况下,考虑对参考完整性约束的外部键作索引。也就是说对表的外键在可能的情况下创建索引以加快操作的速度,改进性能。因为如果对于一张表而言,如果在它的外键上没有索引的话,那么在对它操作的同时,ORACLE将对此外键对应的主表加一个表级锁,以保证数据的完整性和一致性。如果在外键上有索引的的话,那么它就可以通过索引找到主表的ROWID,只对主表加一个行级锁。

    1.6.          如何选择单列索引还是复合索引

    1.6.1.         索引选择性的测量

    所谓索引选择性是指索引中有多少不同的值同表中记录数目的比值,不同的值越多,代表选择性越高,最高的选择性为1(例如唯一性索引)。

    对于索引选择性的测量可以通过不同的方法来进行测量。一种是通过手工的方式作,一种是通过自动的方式来作。

    自动方式来作的是通过对表进行Analyze之后,然后通过查看相应数据字典的值来计算。对索引的不同值可以通过USER_INDEXES.DISTINCT_KEYS查到,表的全部记录数可以通过USER_TABLES.NUM_ROWS查到。在创建索引之前,可能需要查看一下列的不同值的数目,它可以通过USER_TAB_COLUMNS.NUM_DISTINCT查到。

    手工方式,就是对相应的索引列进行DISTINCT操作,然后得到不同值的数目。然后对表进行COUNT(*)函数操作,得到表的记录数目,把两者数据进行比较,就得到索引的选择性。

    1.6.2.         单列索引和复合索引的选择

    对于复合索引而言,主列(第一列)的选择性从很大程度上决定了复合索引的选择性。我们还是举前面的例子来说明如何选择索引的创建。假设我们在Where条件中经常用City=’xxx’and state=’xxx’为条件的话,这时有两种选择,一种是方案1,一种是方案3。假设复合索引同单独索引的选择性差不多的话,那么选择方案3就会有一个AND_EQUAL的操作,会导致比方案1多将近2/3的索引操作,因此需要考虑方案1。又假设在系统中有大量的基于State的Where语句操作,这时还是有两种方案一是方案2,一是方案3。此时如果基于State列上的索引的数据量不大的话,而且相应的附加开销不多的话,基于同上面相同的理由,可以选择方案2。不过如果单列索引同复合索引的选择性相差很大的话又另当别论了。

    附:

    方案

    索引#1

    索引#2

    1

    City,state

    None

    2

    City,state

    State

    3

    City

    State

     

    2.            编写利用索引的SQL语句

    在日常的应用中,索引是否引用是关系到该SQL语句效率的一个非常关键的因素。在日常应用中应该注意到如果在SQL语句中出现下列语法,则系统无法利用到索引:

    u  COLUMN1>COLUMN2

    u  COLUMN1<COLUMN2

    u  COLUMN1>=COLUMN2

    u  COLUMN1<=COLUMN2

    其中COLUMN1和COLUMN2在同一张表中。

    u  COLUMN IS NULL

    u  COLUMN IS NOTNULL

    u  COLUMN NOT IN

    u  COLUMN !=EXPR

    u  COLUMN LIKE‘%ANYTHING’

    在上述条件中不管COLUMN上是否有建索引,SQL语句都不会利用索引。

    u  EXPR是一个表达式,它用运算符或函数操作在该列上,不管列上是否有索引,例如:EXPR*COLUMN=ANYTHING,则不能利用索引。

    u  NOT EXISTSSUBQUERY

    u  不包含未被索引的列的任何条件

    u  在LIKE表达式中如果模糊的列为数字或日期的话,那么该语句同样无法利用索引。

    u  在ORACLE内部的本身的数据转换(DATA CONVERSION)将引起ORACLE索引列的不被使用。

    在日常SQL语句使用时还应该注意使用索引的原则:

    u  在使用复合索引时,应该注意是否有利用到该索引的前导部分(LeadingPosition),在使用该复合索引时只有使用到该索引的前导部分,该索引才能被利用,否则就根本无法发挥索引作用。例如:用户在一张表的三个列(X,Y,Y)张建立一复合索引,该复合索引的顺序为XYZ。在SQL语句的WHERE条件中使用XY,XYZ,XZ等都可利用到索引,但是如果使用YZ,Z等就无法利用到索引。如果对索引的所有列都有引用的话,则无所谓对字段位置的使用了。

    u  对于复合索引,对于主列的操作是否使用索引同样受上面的条件限制。

    u  在SQL语句中尽量避免不要使用不等或者NULL。

    3.            回滚段的作用:介绍回滚段的原理,使用时要注意的事项,从它入手如何提高SQL的效率,使用固有的ORACLE提供的PACKAGE

    具体内容详见相应的回滚段的专题介绍。

    4.            SQL语句HINT的说明

    作为一个应用软件的设计者或者编程人员,应该比Oracle数据库的优化器更清楚数据的分布情况。特别是一个SQL语句有多种执行路径的时候,优化器的选择也许不是最优的,这时就可以通过在语句中使用Hint来指定优化器使用哪种的执行路径。

    4.1.          在哪些语句中允许使用Hint

    并不是任何场合下都允许使用Hint的,只有符合下列情况之一,才有可能使用Hint:

    ²  一个简单的SELECT,UPDATE或者DELETE语句

    ²  一个主查询或者一个复杂语句的子查询

    ²  一个复杂查询的一部分

    4.2.          Hint的书写格式说明

    Hint的书写格式如下:

    (delete,select,update) /*+Hint*/

    或者

    (delete,select,update) --+Hint

    Hint的写法为在几个关键字之后使用SQL语句的注释符(/*Hint*/;--+Hint)来写Hint。此外,如果Hint书写有问题的话,Oracle并不会报错,而是继续使用优化器的执行路径来作。

    4.3.          Hint的分类使用说明

    4.3.1.         优化方式选择

    该类型的Hint等价于在Init参数中使用Optimizer_mode指定优化的方式或者等同对于某一个Session使用Alter session …set optimizer_mode的功能。

    内容包括:All_rows,First_rows,Choose,Rule。

    4.3.1.1.        ALL_ROWS

    语法格式为:/*+ALL_ROWS*/

           该Hint显式的选择Cost_based的方式来优化SQL语句块。它从最小化总体的资源消耗的方面考虑优化,也就是达到整体的输出时间最少。

    4.3.1.2.        FIRST_ROWS

    语法格式为:/*+FIRST_ROWS*/

    该Hint显式的选择Cost_based的方式来优化SQL语句块。它从最佳反馈时间方面来考虑优化,也就是要求使第一条的记录返回时间最短。

    该Hint是优化器有如下选择:

    ²  如果有一个索引可以使用的话,那么优化器将可能会使用索引代替全表扫描。

    ²  如果有一个索引可以使用的话,那么优化器将可能会在对于一个NESTEDLOOPS操作中关联到一个相关的INNER表时,使用NESTED LOOPS JOIN代替SORT-MERGE JOIN操作。

    ²  如果有一个索引可以使用的话,那么优化器将可能会使用它来在一个ORDERBY操作中避免产生一个SORT操作。

    该Hint在什么情况下会被忽略:

    ²  在UPDATE或者DELETE语句中会被忽略

    ²  在下列的SELECT语句中该Hint也会被忽略:数据集操作(UNION,INTERSECT,MINUS,UNIONALL),GROUP BY子句,FOR UPDATE子句,GROUP函数,DISTINCT操作。由于上述操作都需要对全部的数据进行检索,同该Hint的作用(以最短的时间返回第一条记录)相冲突。

    4.3.1.3.        CHOOSE

    语法格式为:/*+CHOOSE*/

    该Hint使优化器在COST_BASED和RULE_BASED的优化模式中选择一种模式。如果在一个语句中关联到的表中有一个表有统计数据,那么优化器就选择COST_BASED的优化模式同时以最佳的输出时间为优化目的(等同于ALL_ROWS)。反之就使用RULE_BASED的优化模式。

    4.3.1.4.        RULE

    语法格式为:/*+RULE*/

    该Hint显式的指定优化器使用RULE_BASED模式。

    4.3.2.         数据访问方式选择

    该类型的Hint包括下列内容:FULL,ROWID,CLUSTER,HASH,HASH_AJ,INDEX,INDEX_ASC,INDEX_COMBINE,INDEX_DES,INDEX_FFS,MERGE_AJ,AND_EQUAL,USE_CONCAT

    4.3.2.1.        FULL

    语法格式如下:/*+FULL(table_name)*/

    该Hint显式的指定优化器对指定table_name进行全表扫描。

    例子:select /*+full(a) Don’t use the index on ACCNO*/ accno,bal

    from accounts a

    where accno=xxxx;

           从上述例子中我们可以对整个Hint的写法有一个更深刻的认识:“Don’t use the index onACCNO”为整个Hint的注释说明,由于在语句的From子句中对表起了一个别名,因此在Hint中的table_name就不能使用真正的表名来代替,而必须使用表的别名。

    4.3.2.2.        ROWID

    语法格式如下:/*+ROWID(table_name)*/

    该Hint显式的指定优化器对指定的table_name的访问通过Rowid来进行。

    4.3.2.3.        CLUSTER

    语法格式如下:/*+CLUSTER(table_name)*/

    该Hint显式的指定优化器对指定的table_name的访问通过Cluster Scan来完成。

    4.3.2.4.        HASH

    语法格式如下:/*+HASH(table_name)*/

    该Hint显式的指定优化器选择HashScan对一个指定的表进行访问。该操作只能对存储在Cluster上表起作用。

    4.3.2.5.        HASH_AJ

    语法格式如下:/*+HASH_AJ*/

    该Hint把一个Not in子查询转换成对一个指定表的hash anti_join访问。

    4.3.2.6.        HASH_SJ

    语法格式如下:/*+HASH_SJ*/

    该Hint把一个Exists子查询转换成对一个指定表的Hash semi_join的访问。

    4.3.2.7.        INDEX

    语法格式如下:/*+INDEX(table_name index_name)*/

    该Hint显式的选择对一个指定表的访问通过指定的索引来进行。

    对于该Hint需要注意的几点是:

    ²  如果在Hint中指定了一个唯一的索引的话,那么优化器就会通过该索引来进行数据检索,而不会考虑全表扫描或者通过其他的索引来进行检索。

    ²  如果在Hint中指定了多个索引的话,那么优化器就会在通过对指定的索引列表进行依次比较,最终选定代价最低的索引来进行检索。优化器不会选择进行全表扫描也不会使用不在Hint中出现的索引列表中的索引。

    ²  如果在Hint中没有指定索引名字的话,优化器会通过对该表上全部的索引进行依次比较,然后最终选定最低的代价的索引进行检索。优化器不会考虑进行全表扫描。

    4.3.2.8.        INDEX_ASC

    语法格式如下:/*+INDEX_ASC(table_name index_name)*/

    该Hint显式的对一个指定的表通过索引进行检索。如果该语句通过索引进行范围检索的话,通过该Hint对该索引的值进行升序检索。此类提示对于基于索引的MIN函数比较有效,只需要作一次查询就可以了。

    4.3.2.9.        INDEX_COMBINE

    语法格式如下:/*+INDEX_COMBINE(table_name index_name)*/

           该Hint主要针对指定表上的bitmap_index。

    4.3.2.10.     INDEX_DESC

    语法格式如下:/*+INDEX_DESC(table_name index_name)*/

    该Hint的整体作用同INDEX_ASC类似,不过是由ASC改为DESC。此类提示对于基于索引的MAX函数比较有效,只需要作一次查询就可以了。

    4.3.2.11.     INDEX_FFS

    语法格式如下:/*+INDEX_FFS(table_name index_name)*/

    该Hint通过对Index的全索引扫描代替全表扫描。

    4.3.2.12.     MERGE_AJ

    语法格式如下:/*+MERGE_AJ*/

    该Hint把一个Not in子查询转换成对一个指定表的merge anti_join访问。

    4.3.2.13.     MERGE_SJ

    语法结构如下:/*+MERGE_SJ*/

    该Hint把一个Exists子查询转换成对一个指定表的merge semi_join的访问。

    4.3.2.14.     AND_EQUAL    

    语法结构如下:/*+AND_EQUAL(table_name index_name index_name…)*/

    该Hint显式的选择一个执行计划,对在不同的单列上的索引的检索结果进行合并。在该Hint中对于index_name至少是2个,但是不能超过5个。

    4.3.2.15.     USE_CONCAT

    语法结构如下:/*+USE_CONCAT*/

    该Hint的作用为把一些OR语句操作强制转化为Union all的集操作。

    4.3.3.         联结顺序

    该类型的Hint内容包括:ORDERED,STAR。

    4.3.3.1.        ORDERED

    语法结构如下:/*+ORDERED*/

    该Hint使Oracle按照From子句中给出的表的顺序进行联结。

    例子:select /*+ordered*/tab1.col1,tab2.col2,tab3.col3

                  from tab1,tab2,tab3

                  where tab1.col1=tab2.col1 andtabl2.col1=tab3.col1

    在此例子中,由于添加了Ordered的Hint,Oracle是把TAB1和TAB2两张表进行Join,然后把Join的结果同TAB3进行再次关联。

    4.3.3.2.        STAR

    语法结构如下:/*+STAR*/

    该Hint主要是用在对于数据仓库这一类数据量比较大的查询。

    4.3.4.         JOIN操作
    4.3.5.         并行操作

    该类型的Hint内容包括:PARALLEL,NOPARALLEL,APPEND,NOAPPEND,PARALLEL_INDEX,NOPARALLEL_INDEX。

    鉴于目前这方面的内容使用的比较少,在此次的文章中暂时不讨论这一类型的Hint的作用和使用。

    4.3.6.         其他

    该类型的Hint内容包括:CACHE,NOCACHE,MERGE,NO_MERGE,PUSH_JOIN_PRED,NO_PUSH_JOIN_PRED,PUSH_SUBQ,STAR_TRANSFORMATION。

    4.3.6.1.        CACHE

    语法格式如下:/*+CACHE(table_name)*/

    大家都知道Oracle对于在buffer中的数据是根据Lru的算法来进行查找的。并且在Lru队列中存在两端,一端为Lru,一端为Mru,对数据的查找和匹配是从Mru开始的。Cache的作用就是使数据Load到Mru上去,使Oracle能够在最短的时间内遍历要查抄的数据,能够在最短的时间内得到结果。该Hint能够覆盖在建表的时候的默认的Cache参数的选项的作用。对于该Hint适合用于对于比较小的表的全表扫描时使用。

    例子:select /*+FULL(scott_emp) CACHE(scott_emp)*/ ename

                  FROM scott.scott_emp;

    4.3.6.2.        NOCACHE

    语法结构如下:/*+NOCACHE(table_name)*/

    该Hint的作用同CACHE的作用相反,它把数据Load到Lru队列的Lru一端。

    对于其他的Hint由于日常使用的不多在这里就不一一介绍了,在日后的文章中有机会在介绍了。

    5.            编写SQL语句的技巧

    5.1.          基本原则

    ²  写相同的SQL语句,保证程序能够利用共享池的内容,加快程序的执行速度。

    ²  写能够利用索引并且能够符合基于代价的优化条件的SQL语句。

    ²  尽量利用PL/SQL的特性减少网络的传输。

    ²  把能够写在服务器端的程序尽可能的不要写在CLIENT端,以减少网络的传输和提高系统的编译速度。

    ²  良好的代码书写习惯

    ²  能够不使用SELECT *的尽量不要使用,除了是为了防止出现在增加字段的时候不需要修改程序外,也是为了保证性能。

    5.2.          尽量避免全表扫描

    在日常编写SQL语句时,除非迫不得已,不然尽量避免下列情况,因为下列情况会导致,系统进行全表扫描来查找数据。

    1、该表上没有任何索引。

    2、一个查询语句中没有任何限制条件,也就是没有Where子句。

    3、对于索引的不适当使用也会导致全表扫描。关于该方面的内容在前面的章节中已经讨论过了。

    4、在进行多张表的联结操作中,如果在from子句中有,但是在where子句中没有用到的表也会导致对该表的全表扫描。

    5.3.          适当索引CONNECT BY操作

    5.4.          限制对远程表的访问

    5.5.          使用UNION ALL代替UNION

    UNION ALL和UNION的操作的最大的区别在于,UNION操作为了保证数据的唯一性,把返回的数据集中的重复的数据去除了。因此,在UNION的执行步骤中包含了SORTUNIQUE的操作。从上个章节的介绍中,我们已经知道了,对于任何一个UNION操作都包含了UNIONALL的操作。并且,从两者的解释计划中,大家可以看到在进行多表的JOIN操作时,UNION是对相应的表进行全表扫描之后再进行UNION ALL的操作,然后进行SORT UNIQUE最后进行NESTED LOOPS,而对于UNION ALL则是先返回相应的小的数据集,然后再进行UNION ALL的操作。

    因此,如果对于返回的数据集不强调数据的唯一性的话,请试用UNION ALL代替UNION。

    5.6.          管理好多表之间的联结

    5.7.          管理好包括视图的查询语句

    5.8.          优化子查询

    5.9.          不要在SQL查询中使用PL/SQL功能调用

    ORACLE公司提供的PL/SQL有着通用SQL无法提供的功能,对简化程序的编写有着不可多得的有点,因此深为大家所喜欢。

    举例来说,大家有时候可能想把数据中的小写数字转换成大写数字,于是,编写了一个函数,实现了该功能,然后在平时在SQL语句中调用该函数来实现数字转换。大大简化了程序的编写,而且也提高了软件的可读性。

    不过,假如从软件的运行效率方面来考虑的话,这种在SQL语句中混合使用PL/SQL的方式是不提倡的。有一个使用数据表明,同样功能的语句,如果是SQL语句调用PL/SQL的方式的话,速度会比正常的慢44倍左右,我们日常中的数值可能会低于这个数字,不过也都有10倍以上。

    因此,总结一句就是不要为了贪图编写方便,而在SQL查询中使用PL/SQL功能调用。

    5.10.      在关键应用中使用OCI代替PL/SQL、PRO*C

    Oracle提供了三种对数据库操作和管理的方式,那就是OCI、PRO*C、PL/SQL。在这三种方式中OCI能够更直接调用操作系统的API,因此能够更直接的到达系统的内核,所以速度比PRO*C、PL/SQL都快。并且,OCI比起其余另外两种方式在HA方面的性能表现的更好。因此,建议对于所有的会话关键型应用程序使用OCI。

    5.11.      在OLAP应用中使用复合的KEYS/STAR查询

    四.    日常SQL TUNING工具的使用

    1.            基础准备工作

    在Oracle的Rdbms系统中,对于系统的优化的选择有两种方式,一种是Cost_based(基于代价),一种是Rule_based(基于规则)。在我们现在的系统中大部分是使用Cost_based的优化策略。如果采用Cost_based的优化策略的话,因此它的一切工作都是以统计值为基础。因此,对于相应的对象必须进行分析(Analyze),这样在相应的系统视图中才有统计值,才能真正使用Cost_based的优化。

    在下面介绍的工具中,都需要看一个东西,那就是执行计划。正如其他的Oracle系统数据一样,执行计划也是存储于表中,这张表就是Plan_table。在正常的时候,这张表是不存在,必须人工创建。创建它的方法如下:

    在需要进行分析的用户下,执行UTLXPLAN.SQL。该脚本存放在$ORACLE_HOME/RDMBS/ADMIN目录下。对于,安装DEVELOPER/2000的用户可在\ORAWIN95\RDBMS73\ADMIN下找到。该脚本建立一张名为PLAN_TABLE的表。用户也可根据自己的需要,把该表的表名改为用户需要的名称。如果,该用户无建表权限,则可在某一用户下建立该表,通过该用户对其余用户进行授权。需要授的权限包括:SELECT,DELETE,INSERT等权限。

    我们在日常编写应用程序的过程中,可以尝试着从以下几种方法来查看,自己使用的SQL语句的效率是否最优。

    l  EXPLAIN PLAN:一种最原始的查看SQL语句的执行计划的方法。

    l  SET AUTOTRACE:一种增强型的EXPLAIN PLAN,可以帮助大家省去许多烦琐的过程。

    l  TKPROF:一个应用级的跟踪工具,可以明确标明系统的CPU消耗时间,IO的情况以及语句的执行计划等信息。

    2.            EXPLAIN PLAN的使用

    它的语法结构如下:explain plan set statementid='text' for statement

    其中对于statementid为用户任意设置的值,而statement为今后在系统中要执行的语句,也就是当前要分析的语句。

    经过EXPLAIN PLAN分析出来的结果存放在PLAN_TABLE中,想对分析出来的结果进行分析,就必须对PLAN_TABLE中的数据进行分析。一般情况下,用如下语句对分析出来的结果进行分析:

    select id,parent_id,position,operation,options,object_name,object_type,costfrom plan_table;

    3.            SET AUTOTRACE 的使用

    在ORACLE中提供了一更方便、更有效的数据存取路径解释方案,它就是在SQL*PLUS中设置AUTOTRACE ON,通过该方法,可以得到该语句的执行计划和相应的统计数据,这些数据包括(For Example):

          15 recursive calls

           0 db block gets

           4 consistent gets

           0 physical reads

           0 redo size

         284 bytes sent via SQL*Net to client

         244 bytes received via SQL*Net from client

           3 SQL*Net roundtrips to/from client

           0 sorts (memory)

           0  sorts (disk)

    要完成上述功能就必须先完成如下事情:以SYS用户登录,执行c:\orawin95\plus33\plustrce.sql通过该SQL语句创建PLUSTRACE这一ROLE,同时在SYS用户下把该ROLE授权给PUBLIC,使一般用户都可使用到该ROLE。

    对于它有如下用法:set autotrace on(off/trace)

    4.            TKPROF的使用

    1)     在使用TKPROF前要作的准备工作

    针对不同环境下对不同的跟踪要求需作的准备工作不同:

    u  对于需要进行分阶段跟踪的用户可通过如下操作进行跟踪,使本身处在受跟踪的环境下,该命令如下:alter session setsql_trace=true,如果想把该跟踪屏蔽,则命令如下:alter session set sql_trace=false或可以通过PACKAGE DBMS_SESSION.SET_SQL_TRACE(ACTION)

    u  对于DBA用户如果想使某一用户的的处理受跟踪,使用的命令如下:dbms_system.set_sql_trace_in_session(sid,serial#,action);其中sid,serial通过V$SESSION这一VIEW得到数据, 写法如下:selectsid,serial# from v$session where username=‘要跟踪的用户名’,action为TRUE、FALSE,如果actio为TRUE则要进行跟踪,如果为FALSE则要取消跟踪。

    u  如果想对在用的每一个用户都进行性能跟踪的话,那么进行如下处理,在INITSID_NAME.ORA中增加如下参数:

    TIMED_STATISTICS:该项的值可设置为TRUE、FALSE,通过该参数可以启用在性能跟踪时的时间统计,平常系统在不作性能跟踪时,最好不要打开该参数,因为该参数会造成对低层操作的额外定时调用,会导致系统性能的部分下降。

    MAX_DUMP_FILE_SIZE:设置系统TRACE文件的大小,该单位以操作系统的BLOCK(块)进行计算,默认为500。

    USER_DUMP_DEST:决定系统的TRACE文件最终存储的路径。

    SQL_TRACE:通过对该参数设置TRUE或FALSE使系统的跟踪可用或不可用。

    2)     如何使用TKPROF  

    通过1)步骤产生的文件的命名规则如下,该文件以ORA打头、TRC为文件的扩展名。总的来讲,该TRACE文件的以下列形式构成:ORA_SPID.TRC。TKPROF的命令行格式如下:

    tkproftrace_file_name output_file_name insert=sql_trace_file_name sys=yes/noexplain=username/password

    其中,TRACE_FILE_NAME指通过跟踪产生的TRC文件,OUTPUT_FILE_NAME指TKPROF分析后产生的分析文件的名称。INSERT子句代表用户经过分析之后形成脚本,其中SQL_TRACE_FILE_NAME代表用户分析后形成的用户SQL脚本的文件名称。SYS=YES代表是对系统语句进行分析,SYS=NO代表不对系统语句进行分析。EXPLAIN子句代表是否对TRC文件中语句进行并列出相应语句的执行计划。

    3)     如何对TKPROF产生的结果进行分析

    对于每一个SQL语句,每一行相对应于三阶段,此三阶段为PARSE,EXECUTE,FETCH,此三阶段的分别含义为:

    PARSE:此步骤将SQL语句翻译成一个执行计划。此步骤包括对正确的安全认可检查,以及表、列和其它要参考的对象的存在性的检查。

    EXECUTE:此步骤为ORACLE对语句的实际执行。对于UPDATE,DELETE和INSERT语句,此步骤修改数据。对于SELECT语句,此步骤识别要选择的行。

    FETCH:此步骤返回由查询返回的行。此步骤只对SELECT语句有效。

    对于每一个分析出来的文件,在其开头部分都有如下一段一段提示:

    count     =number of  times OCIprocedure was executed

    cpu        =cpu time in seconds executing

    elapsed  =elapsed time in seconds executing

    disk              =number of physical reds of buffers from disk

    query     =number of buffers gotten ofr consistent read

    current  =number of buffers gotten in currentmode(usually for update)  

    rows      =number of rows processed by the fetch or execute call

    上述的提示中提到的关键字是今后在对系统进行分析时,要用到的所有语法分析,所有执行和所有取数的组合统计,具体的中文含义如下:

    ²  Count    一个语句被语法分析、执行和取数的次数。

    ²  Cpu              对语句的所有语法分析,执行或取数调用的总CPU时间(以秒计)。

    ²  Elapsed 对语句的所有语法分析,执行或取数调用的总耗费时间(以秒计)。

    ²  Disk             对所有语法分析,执行或取数调用的,从磁盘数据文件上数据块物理读的总数。

    ²  Query    对所有语法分析,执行或取数调用的,以一致方式检索的缓冲区总数,对查询来说,通常用一致性方式检索缓冲区。

    ²  Current  以当前方式检索的缓冲区总数。对INSERT,UPDATE和DELETE语句通常用当前方式检索缓冲区。

             Query和current的和是存取的缓冲区的总数。

    ²  Rows     由SQL语句处理的总行数。对于SELECT语句而言,返回的行数出现在取数的步骤,对UPDATE、DELETE和INSERT语句而言,处理的行数出现在执行步骤。

    展开全文
  • C++文件操作:打开文件和写入文件

    千次阅读 2019-05-29 09:11:47
    如果程序的运行结果仅仅显示在屏幕上,当要再次查看结果时,必须将程序重新运行遍;而且,这结果也不能被保留。 如果希望程序的运行结果能够永久保留下来,供随时查阅或取用,则需要将其保存在文件中。 文件分类...
  • input其后能够跟变量列表,也就是能够将内容分别赋值给几个变量,在文本中用逗号分隔开,也就是说,文本中第一个逗号(英文半角逗号)之前的给变量列表里面的第一个变量,第一个逗号之后,第二个
  • 转贴自 http://www.excelperfect.com/2009/08/06/handlefileswithvba2/ 使用VBA操作文件(2):处理文件的VBA函数和语句下面主要介绍专门用于处理文件和文件夹的VBA函数。CurDir函数CurDir函数用于获取当前文件夹的...
  •  打开顺序文件,我们可以使用Open语句。它的格式如下: Open pathname For [Input |Output |Append] As [#]filenumber [Len = buffersize]  说明:  (1)参数pathname 表示要打开的文件名,文件名可以...
  • 【C】C语言文件(包括:文件各种读写方式)

    万次阅读 多人点赞 2018-05-09 09:52:32
    文件概述 文件是指存储在外部存储器上的数据集合。更准确的来说,文件就是一组...ASCII文件(文本文件):以字符的方式进行存储,一个字符对应一个ASCII码,而一个ASCII码占用1字节。例如:整数12在内存中占用4个字...
  • 条SQL语句的执行流程前言MySQL架构 前言 MySQL架构
  • 5-Python-文件操作、异常、模块

    万次阅读 2017-05-24 14:55:46
    知识点 文件操作 &lt;1&gt;打开文件 ...在python,使用open函数,可以打开一个已经存在的文件,或者创建一个文件 ... 以只读方式打开文件文件的指针将会放在文件的... 打开一个文件用于写入。如果该...
  • Oracle 常用语句大全

    万次阅读 2018-12-13 00:13:10
    、基础必会篇 1、说明:创建数据库 CREATE DATABASE database-name 2、说明:删除数据库 drop database dbname 3、说明:备份 sql server — 创建 备份数据的 device USE master EXEC sp_addumpdevice ‘disk’, ...
  • (2)、catch:后面对应异常类型和一个代码块,用于表明该catch块用于处理这种类型的代码块,可以有多个catch块。 (3)、finally:主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件),异常...
  • linux环境变量文件区别&加载顺序

    千次阅读 2018-06-14 13:14:17
    :为每一个运行bash shell的用户执行此文件,当bash shell被打开时,该文件被读取。 2 .bashrc和.bash_profile的区别 .bash_profile会用在登陆shell, .bashrc 使用在交互式非登陆 shell 。简单说来,它们...
  • SQL命令和常用语句大全

    千次阅读 2016-05-22 21:41:32
    学习SQL应知道的动态SQL语句基本语法 1 、普通SQL语句可以用Exec执行 9Kp=A ' CdaFr1 eg: Select * from tableName Wsc+A: Exec('select * from tableName') #Btn( Exec sp_executesql N'select * from ...
  • 如何写一个仿真文件——testbench

    千次阅读 多人点赞 2020-04-29 17:25:08
    testbench就是对写的FPGA文件进行测试的文件。任何设计都是有输入输出的,testbench的作用就是给这设计输入,然后观察输出是否符合我们的预期,这就是testbench的功能。运行环境一般是ise或者vivado自带的仿真工具...
  • SQL常用语句总结

    千次阅读 2012-08-29 09:18:50
    open --检索查询结果打开一个游标  fetch --检索一行查询结果  close --关闭游标  prepare --为动态执行准备SQL 语句  execute --动态地执行SQL 语句  describe --描述准备好的查询 ----------...
  • 经典SQL语句大全

    万次阅读 多人点赞 2019-05-10 10:01:53
    经典SQL语句大全 来源::https://www.cnblogs.com/1234abcd/p/5530314.html ** 、基础 ** 1、说明:创建数据库 CREATE DATABASE database-name 2、说明:删除数据库 drop database dbname 3、说明:备份...
  • Python文件操作 打开,读取,关闭

    千次阅读 2010-06-18 16:39:00
    >>> f = open(”d:test.txt”, “w”) 说明:第一个参数是文件名称,包括路径;第二个参数是打开的模式mode’r':只读(缺省。如果文件不存在,则抛出错误)’w':只写(如果文件 不存在,则自动创建文件)...
  • shell中的if语句使用说明

    千次阅读 2019-08-15 09:27:35
    语法 1、基本语法: if [ command ]; then # 符合该条件执行的语句 fi 1.1 使用else: if [ command ]; then # 符合该条件执行的语句1 elif [ command ];... # 符合该条件执行的语句2 ...bash shell会按顺序执行...
  • oracle笔记(sql语句方面)

    万次阅读 2011-07-04 09:23:50
    oracle笔记(sql语句方面) .sql语句--================================================1.增加主键 alter table TABLE_NAME add constraint KEY_NAM
  • shell中的if语句

    千次阅读 2019-07-10 09:28:10
    1、基本语法: if [ command ]; then 符合该条件执行的语句 fi 2、扩展语法: ... 符合该条件执行的语句 ... 符合该条件执行的语句 ... 符合该条件执行的语句 ... bash shell会按顺序执行if语句,如果com...
  • MySQL基本语句大全

    万次阅读 2018-06-09 19:28:55
    3),例如:在一个外部表中导入数据,由于某些原因第一次只导入了一部分,但很难判断具体位置,这样只有在下一次全部导入,这样也就产生好多重复的字段,怎样删除重复字段 alter table tablename –添加一个自增列...
  • sql语句优化

    万次阅读 多人点赞 2013-01-01 19:53:03
    sql语句优化 性能不理想的系统中除了部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化。为了获得稳定的执行性能,SQL语句越简单越好。对复杂的SQL语句,要...
  • Nginx配置文件(nginx.conf)配置详解

    万次阅读 多人点赞 2016-02-19 10:03:50
    Nginx的配置文件nginx.conf配置详解如下: usernginxnginx; Nginx用户及组:用户组。window下不指定 worker_processes8; 工作进程:数目。根据硬件调整,通常等于CPU数量或者2倍于CPU。 error_loglogs/error.log;...
  • 【C语言】文件(FILE)

    万次阅读 多人点赞 2019-04-05 23:19:07
    文章目录文件1.1 文件类型指针1.2 文件打开与关闭1.2.1 文件打开1.2.2 文件的关闭1.3 文件的读写1.3.1 文本文件的读写1.3.1.1 写字符函数fputc和读字符函数fgetc1.3.1. 2 写字符串函数fputs和读字符串函数...
  • 这个数据集有一个名称,叫做文件名。实际上在前面的各章中我们已经多次使用了文件,例如源程序文件、目标文件、可执行文件、库文件 (头文件)等。文件通常是驻留在外部介质(如磁盘等)上的,在使用时才调入内存中来。...
  • 本文成于2019年12月25日 ...简单介绍下promise Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法。 那就new一个 var p = new Promise(func...
  • SQL语句

    千次阅读 2005-02-18 13:24:00
    关于ODBC数据源连接文本 在《外部数据库的连接原理》讲中我们说过,ODBC提供对多种数据库的支持,如dBase、Access、MS SQL Server及Oracle,也就是说运用ODBC数据源中所提供的连接代码,我们可以实现对多种数据库...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 119,907
精华内容 47,962
关键字:

以下语句用于打开一个顺序文件