精华内容
下载资源
问答
  • Oracle数据库索引

    千次阅读 2015-08-18 15:33:26
    Oracle数据库索引  本文标签:Oracle数据库 索引   导读:数据库在当代社会中的地位是越来越高,干什么都似乎离不开数据库,所以,掌握好数据库是在社会中立足的条件 。如果你在数据库方面是一个新手,又...
    
    

    Oracle数据库索引


      本文标签:Oracle数据库 索引 

      导读:数据库在当代社会中的地位是越来越高,干什么都似乎离不开数据库,所以,掌握好数据库是在社会中立足的条件  。如果你在数据库方面是一个新手,又或者你对Oracle数据库不是很熟悉,那你可能会发现关于索引和构建索引策略方面的讨论资料看起来很艰涩  。不过,只要你对于能满足数据库管理员日常管理相关的选项稍加注意,其实要入手还是很容易的  。

      1)b-tree索引

      Oracle数据库中最常见的索引类型是b-tree索引,也就是B-树索引,以其同名的计算科学结构命名  。每当你发布基本的没有经过进一步修改的CREATEINDEX语句时,就是在创建b-tree索引  。这里不打算对b-tree索引进行更多深入的探讨,这些用户都可以自己了解  。基本上这些索引存储你创建的索引所在的列值以及用来查找自身行的指向实际数据表的指针  。记住,这也就意味着要进行多路查询,其中一个查询各个节点和索引的叶节点,然后才是表的行自身  。这就是为什么Oracle的优化器在某种情况下会选择执行全表扫描而不执行索引查找的原因了,因为全表扫描执行起来实际上可能会更快一些  。还要注意的是,如果你的索引是创建在多个列上的话,那么第一列(leadingcolumn)非常重要  。假设你有一个多列索引(也称为级联索引),索引列的排列顺序是c列到d列,你可以对使用该索引c列单独进行一次查询,但你不能使用该索引对d列冶金行一次单独的查询  。

      2)基于函数的索引

      如果在搜索时你读取很多行,或者你的索引选择性不大,又或者你在级联索引中使用了第一列以外的列,Oracle数据库有时候会选择不使用索引  。那么如果你想要执行一个大小写不敏感的搜索呢?像下面的指令:WHEREUPPER(first_name)= "JOHN"  。

      这也不会使用first_name字段上的索引  。为什么?因为Oracle不得不将UPPER函数用在该索引所有(ALL)的值上,所以还不如做一次全表扫描  。所以,很多时候Oracle创建基于函数的索引就是为了这个目的  。

      3)反转关键字索引

      你还可以看到这些反转关键字索引,而且不时还要用到这些索引  。假设有一列包含了“餐厅甲”、“餐厅乙”、“餐厅丙”等类似名字  。可能这不是一个很好的例子,不过关键的一点是拥有很多唯一值,但其关键字的前面一部分变化不大  。因为Oracle会在将REVERSE关键字指定给b-tree前把REVERSE字符串简化,所以使用反转关键字索引可能是最好的  。这样的一个索引可能更平衡、有用,搜索起来更快  。

      更多外部索引类型

      Oracle还提供了很多更为复杂的索引类型  。不过请注意,你最好全面阅读过相关的说明文档后再使用这些索引,因为它们各自都有各自特定的适用范围  。

      1)位图索引(bitmapindex)

      假设数据库表中有一列其选择性非常窄,例如性别列,该用什么类型的索引?你可能会考虑对其使用位图索引  。因为位图索引正是为相异值很少的列而创建的  。但需要考虑的因素还不只这些  。一般而言,只有当你对表中值相宜度较小的多个不同的列都使用位图索引,这样位图索引才有用,因为你可以一起使用这些索引才能对列产生更大的选择性,否则你还是需要对这些列进行一次全表扫描  。例如,对于性别列,其索引只能有两个唯一值,那么用这个索引对表的任何搜索有可能都返回一半的记录  。其次,这些索引是为数据仓库设计的,所以其假定条件是数据不会发生很大的改变  。这些索引不能用来满足事务数据库或更新频繁的数据库  。应该说,对位图索引的表进行更新根本没有一点效率  。

      2)位图连接索引(bitmap join index)

      位图连接索引比位图索引更进了一步  。这些索引将位图化的列完全从表数据中抽取出来,并将其存储在索引中  。其假定条件是这些列集合必须一起查询  。同样的,这也是为数据仓库数据库而设计的  。除了在句法最后有一个WHERE子句之外,位图连接索引的创建指令就像创建位图索引的CREATEBITMAPINDEX一样  。

      3)压缩索引

      压缩索引实际是标准b-tree索引的一个选项  。压缩索引的叶节点更少,所以总的I/O数量和需要的缓存也更少  。这些都意味着Oracle的优化器更可能使用这些压缩索引,而不倾向于使用标准的非压缩索引  。不过,这些好处也是有代价的,当你对这些压缩索引进行存取操作时,要消耗更多的CPU来进行解压缩  。而且,当你阅读关于优化器如何使用这些索引,又是如何选择合适的压缩级别的资料时,就开始变得晦涩了  。不同的用户不同的设置从压缩索引中得到的好处也可能会有所不同  。

      4)降序索引(descending index)

      这是基于函数索引的一种特殊类型  。降序索引可以显著优化ORDER BY x, y, z DESC子句查询的  。

      5)分区索引(partitioned index)

      如果你的数据库中有一个分区表,你就有机会体验几种新的索引类型,从贯穿所有分区的全局分区索引(global)和集中于各个单独分区的本地分区索引(local)  。这里不再进行赘述,想知道细节问题可以查询相关文献  。

      6)索引组织表(index organized table,IOT)

      这是在Oracle9i中引进的一种新类型表  。Oracle会将级联索引及其扩展类型的索引用于表中所有的列  。当所有数据都载入到索引结构之后,表就成多余的了,你尽可以将表本身删除掉  。这就是索引组织表  。

      7)簇索引(cluster index)

      基本上,簇索引就是将多个表的相同列放在一起,而对该列使用用一个簇索引  。这种索引在实际应用比较少,因为还有各种有待解决性能问题存在  。

      8)域索引(domain index)

      当我们创建为用户定义数据类型(datatype)创建用户自定义索引类型(indextype)时就要使用域索引  。

      9)隐藏索引(invisible index)

      这是Oracle11g中推出的新特性  。其创建过程和标准索引一样,但创建后对于基于代价的优化器(CBO)是不可见的  。这可以让你对性能进行大型测试查询,而不会影响现有的正在运行的应用程序  。

      10)虚拟索引(virtual index)

      这是为测试人员和开发人员准备的又一个工具  。虚拟索引(不分配段空间)可以让你在不需要实际创建索引的情况下,测试新索引及其对查询计划的影响  。对于GB级的表来说,构建索引非常耗费资源而且还要占用大量时间  。

      11)其他的索引类型

      Oracle数据库还提供了很多其他类型的索引,例如用来为字符型大型二进制对象(CLOB)或其他大型文本数据构建索引的OracleTEXT,OracleSpatial等  。有兴趣的读者可以自己查找相关资料了解  。

      都是为了优化器

      如果你曾经广泛接触过MySQL和其他的数据库,你会发现甲骨文虽然是全球领先的数据库供应商,但它们的数据库对于用户来说用起来其实并不是很方便  。提到优化器这个问题可能有点离题了,不过Oracle数据库最基本的食料就是优化器了,这的确是种挺特别的调料,而且变得越来越美味了  。市面上有很多以Oracle基于代价的优化器(CostBasedOptimizer,CBO)为主题内容的书籍,专门介绍分析表和索引的技巧和策略  。

      对于数据库,除了需要一直更新你的统计信息之外,你可能还需要不断测试新的查询  。使用解析计划机制,并进行优化以便减少总I/O量以及排序合并数据的计算量,只有这样你才能获得更好的性能表现  。

      总结

      上文主要讲述了Oracle数据库索引的基本知识,对刚刚入门的初学者是很好的学习资料  。虽然Oracle数据库的索引世界有点吓人,不过实际上你平常经常使用的索引就只有那么一些  。而且,不管唱反调的人怎样诋毁,Oracle的优化器都已经设计相当出色;总体而言,Oracle很擅长于让你的数据库运行地更有效率  。虽然这并不意味着你不需要对自己的SQL进行调优,不过,如果你一直保持着最新的统计信息,并让Oracle为你整理出你所需要的最小数据集的话,它能够以极快的速度满足你的需要  。


    在关系数据库中,索引是一种与表有关的数据库结构,它可以使对应于表的SQL语句执行得更快。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。 

    对于数据库来说,索引是一个必选项,但对于现在的各种大型数据库来说,索引可以大大提高数据库的性能,以至于它变成了数据库不可缺少的一部分。

     

    索引分类:

    逻辑分类

    single column or concatenated     对一列或多列建所引

    unique or nonunique    唯一的和非唯一的所引,也就是对某一列或几列的键值(key)是否是唯一的。

    Function-based    基于某些函数索引,当执行某些函数时需要对其进行计算,可以将某些函数的计算结果事先保存并加以索引,提高效率。 

    Doman    索引数据库以外的数据,使用相对较少

     

    物理分类

    B-Tree normal or reverse key   B-Tree索引也是我们传统上常见所理解的索引,它又可以分为正常所引和倒序索引。

    Bitmap  : 位图所引,后面会细讲

     

      

    B-Tree 索引                                                                                 

     

      B-Tree index 也是我们传统上常见所理解的索引。B-tree balance tree)即平衡树,左右两个分支相对平衡。

    B-Tree index

    Root为根节点,branch 为分支节点,leaf 到最下面一层称为叶子节点。每个节点表示一层,当查找某一数据时先读根节点,再读支节点,最后找到叶子节点。叶子节点会存放index entry (索引入口),每个索引入口对应一条记录。

    Index entry 的组成部分:

    Indexentry entry  header    存放一些控制信息。

    Key column length     某一key的长度

    Key column value      某一个key 的值

    ROWID    指针,具体指向于某一个数据

     

    创建索引:

    复制代码
    用户登录:
    SQL> conn as1/as1
    Connected.
    
    创建表:
    SQL> create table dex (id int,sex char(1),name char(10));
    Table created.
    
    向表中插入1000条数据
    SQL> begin
      2  for i in 1..1000
      3  loop
      4  insert into dex values(i,'M','chongshi');
      5  end loop;
      6  commit;
      7  end;
      8  /
    
    PL/SQL procedure successfully completed.
    
    查看表记录
    SQL> select * from dex;
            ID SE NAME
    ---------- -- --------------------
           ... . .....
    
           991 M  chongshi
           992 M  chongshi
           993 M  chongshi
           994 M  chongshi
           995 M  chongshi
           996 M  chongshi
           997 M  chongshi
           998 M  chongshi
           999 M  chongshi
          1000 M  chongshi
    
    1000 rows selected.
    
    创建索引:
    SQL> create index dex_idx1 on dex(id);
    Index created.
    注:对表的第一列(id)创建索引。
    
    查看创建的表与索引
    SQL> select object_name,object_type from user_objects;
    
    OBJECT_NAME                  OBJECT_TYPE
    --------------------------------------------------------------------------------
    DEX                           TABLE
    DEX_IDX1                      INDEX
    复制代码

      索引分离于表,作为一个单独的个体存在,除了可以根据单个字段创建索引,也可以根据多列创建索引。Oracle要求创建索引最多不可超过32列。

    复制代码
    SQL> create index dex_index2 on dex(sex,name);
    Index created.
    
    SQL>  select object_name,object_type from user_objects;
    
    OBJECT_NAME                           OBJECT_TYPE
    --------------------------------------------------------------------------------
    DEX                                       TABLE
    DEX_IDX1                                 INDEX
    DEX_INDEX2                               INDEX
    复制代码

     

    这里需要理解:

      编写一本书,只有章节页面定好之后再设置目录;数据库索引也是一样,只有先插入好数据,再建立索引。那么我们后续对数据库的内容进行插入、删除,索引也需要随之变化。但索引的修改是由oracle自动完成的。

    上面这张图能更加清晰的描述索引的结构。

    跟节点记录050条数据的位置,分支节点进行拆分记录010.......4250,叶子节点记录每第数据的长度和值,并由指针指向具体的数据。

    最后一层的叶子节是双向链接,它们是被有序的链接起来,这样才能快速锁定一个数据范围。

    如:

    复制代码
    SQL> select * from dex where id>23 and id<32;
    
            ID SE NAME
    ---------- -- --------------------
            24 M  chongshi
            25 M  chongshi
            26 M  chongshi
            27 M  chongshi
            28 M  chongshi
            29 M  chongshi
            30 M  chongshi
            31 M  chongshi
    
    8 rows selected.
    复制代码

      如上面查找的列子,通过索引的方式先找到第23条数据,再找到第32条数据,这样就能快速的锁定一个查找的范围,如果每条数据都要从根节点开始查找的话,那么效率就会非常低下。

     

     

    位图索引                                                                        

     

      位图索引主要针对大量相同值的列而创建。拿全国居民登录一第表来说,假设有四个字段:姓名、性别、年龄、和身份证号,年龄和性别两个字段会产生许多相同的值,性别只有男女两种值,年龄,1120(假设最大年龄120岁)个值。那么不管一张表有几亿条记录,但根据性别字段来区分的话,只有两种取值(男、女)。那么位图索引就是根据字段的这个特性所建立的一种索引。

    Bitmap Index

      从上图,我们可以看出,一个叶子节点(用不同颜色标识)代表一个key , start rowid 和 end rowid规定这种类型的检索范围,一个叶子节点标记一个唯一的bitmap值。因为一个数值类型对应一个节点,当时行查询时,位图索引通过不同位图取值直接的位运算(与或),来获取到结果集合向量(计算出的结果)。

     

    举例讲解:

    假设存在数据表T,有两个数据列A和B,取值如下,我们看到A和B列中存在相同的数据。

    对两个数据列A、B分别建立位图索引:idx_t_bita和idx_t_bitb。两个索引对应的存储逻辑结构如下:

    Idx_t_bita索引结构,对应的是叶子节点:

    Idx_t_bitb索引结构,对应的是叶子节点:

     

    对查询“select * from t where b=1 and (a=’L’ or a=’M’)

    分析:位图索引使用方面,和B*索引有很大的不同。B*索引的使用,通常是从根节点开始,经过不断的分支节点比较到最近的符合条件叶子节点。通过叶子节点上的不断Scan操作,“扫描”出结果集合rowid。

    而位图索引的工作方式截然不同。通过不同位图取值直接的位运算(与或),来获取到结果集合向量(计算出的结果)。

    针对实例SQL,可以拆分成如下的操作:

    1、a=’L’ or a=’M’

    a=L:向量:1010

    a=M:向量:0001

    or操作的结果,就是两个向量的或操作:结果为1011。

     

    2、结合b=1的向量

    中间结果向量:1011

    B=1:向量:1001

    and操作的结果,1001。翻译过来就是第一和第四行是查询结果。

     

    3、获取到结果rowid

    目前知道了起始rowid和终止rowid,以及第一行和第四行为操作结果。可以通过试算的方法获取到结果集合rowid。

     

    位图索引的特点

    1.Bitmap索引的存储空间节省 

    2.Bitmap索引创建的速度

    3.Bitmap索引允许键值为空 

    4.Bitmap索引对表记录的高效访问

     

    创建位图索引:

    复制代码
    查看表记录
    SQL> select * from dex;
    ...................
            ID SEX NAME
    ---------- -- --------------------
           991 M  chongshi
           992 M  chongshi
           993 G  chongshi
           994 G  chongshi
           995 G  chongshi
           996 M  chongshi
           997 G  chongshi
           998 G  chongshi
           999 G  chongshi
          1000 M  chongshi
    
    1000 rows selected.
    
    对于上面表来说sex(性别)只有两种值,最适合用来创建位图所引
    创建索引:
    SQL> create bitmap index my_bit_idx on dex(sex);
    
    Index created.
    
    查看创建的所引
    SQL>  select object_name,object_type from user_objects;
    
    OBJECT_NAME                           OBJECT_TYPE
    --------------------------------------------------------------------------------
    MY_BIT_IDX                               INDEX
    复制代码

     

     

     

    创建索引的一些规则                                                   

     

    1、权衡索引个数与DML之间关系,DML也就是插入、删除数据操作。

    这里需要权衡一个问题,建立索引的目的是为了提高查询效率的,但建立的索引过多,会影响插入、删除数据的速度,因为我们修改的表数据,索引也要跟着修改。这里需要权衡我们的操作是查询多还是修改多。

    2、把索引与对应的表放在不同的表空间。

         当读取一个表时表与索引是同时进行的。如果表与索引和在一个表空间里就会产生资源竞争,放在两个表这空就可并行执行。

    3、最好使用一样大小是块。

         Oracle默认五块,读一次I/O,如果你定义6个块或10个块都需要读取两次I/O。最好是5的整数倍更能提高效率。

    4、如果一个表很大,建立索引的时间很长,因为建立索引也会产生大量的redo信息,所以在创建索引时可以设置不产生或少产生redo信息。只要表数据存在,索引失败了大不了再建,所以可以不需要产生redo信息。

     

    5、建索引的时候应该根据具体的业务SQL来创建,特别是where条件,还有where条件的顺序,尽量将过滤大范围的放在后面,因为SQL执行是从后往前的。(小李飛菜刀

     

    索引常见操作                                                            

     

    改变索引

    SQL> alter index employees_last _name_idx storage(next 400K maxextents 100);

    索引创建后,感觉不合理,也可以对其参数进行修改。详情查看相关文档

     

    调整索引的空间:

    复制代码
    新增加空间
    SQL> alter index orders_region_id_idx allocate extent (size 200K datafile '/disk6/index01.dbf');
    
    释放空间
    SQL> alter index oraers_id_idx deallocate unused;
    复制代码

    索引在使用的过程中可能会出现空间不足或空间浪费的情况,这个时候需要新增或释放空间。上面两条命令完成新增与释放操作。关于空间的新增oracle可以自动帮助,如果了解数据库的情况下手动增加可以提高性能。

     

    重新创建索引

    所引是由oracle自动完成,当我们对数据库频繁的操作时,索引也会跟着进行修改,当我们在数据库中删除一条记录时,对应的索引中并没有把相应的索引只是做一个删除标记,但它依然占据着空间。除非一个块中所有的标记全被删除的时,整个块的空间才会被释放。这样时间久了,索引的性能就会下降。这个时候可以重新建立一个干净的索引来提高效率。

    SQL> alter index orders_region_id_idx rebuild tablespace index02;

    通过上面的命令就可以重现建立一个索引,oracle重建立索引的过程:

    1、锁表,锁表之后其他人就不能对表做任何操作。

    2、创建新的(干净的)临时索引。

    3、把老的索引删除掉

    4、把新的索引重新命名为老索引的名字

    5、对表进行解锁。

     

    移动所引

    其实,我们移动索引到其它表空间也同样使用上面的命令,在指定表空间时指定不同的表空间。新的索引创建在别位置,把老的干掉,就相当于移动了。

    SQL> alter index orders_region_id_idx rebuild tablespace index03;

     

    在线重新创建索引

    上面介绍,在创建索引的时候,表是被锁定,不能被使用。对于一个大表,重新创建索引所需要的时间较长,为了满足用户对表操作的需求,就产生的这种在线重新创建索引。

    SQL> alter index orders_id_idx  rebuild  online;

    创建过程:

    1、锁住表

    2、创建立临时的和空的索引和IOT表用来存在on-going DML。普通表存放的键值,IOT所引表直接存放的表中数据;on-gong DML也就是用户所做的一些增删改的操作。

    3、对表进行解锁

    4、从老的索引创建一个新的索引。

    5、IOT表里存放的是on-going DML信息,IOT表的内容与新创建的索引合并。

    6、锁住表

    7、再次将IOT表的内容更新到新索引中,把老的索引干掉。

    8、把新的索引重新命名为老索引的名字

    9、对表进行解锁

     

    整合索引碎片

    如上图,在很多索引中有剩余的空间,可以通过一个命令把剩余空间整合到一起。  

    SQL> alter index orders_id_idx  coalesce;

     

    删除索引

    SQL> drop  index  hr.departments_name_idx;

     

     

     

    分析索引                                                                                  

      

      检查所引的有效果,前面介绍,索引用的时间久了会产生大量的碎片、垃圾信息与浪费的剩余空间了。可以通过重新创建索引来提高所引的性能。

    可以通过一条命令来完成分析索引,分析的结果会存放在在index_stats表中。

    复制代码
    查看存放分析数据的表:
    SQL> select count(*) from index_stats;
    
      COUNT(*)
    ----------
             0
    执行分析索引命令:
    SQL> analyze index my_bit_idx validate structure;
    
    Index analyzed.
    
    再次查看 index_stats 已经有了一条数据
    SQL> select count(*) from index_stats;
    
      COUNT(*)
    ----------
             1
    
    把数据查询出来:
    SQL> select height,name,lf_rows,lf_blks,del_lf_rows from index_stats;
    
        HEIGHT   NAME              LF_ROWS   LF_BLKS   DEL_LF_ROWS
    ---------- ---------------------------------------------------------------------- ---------- -----------
             2   MY_BIT_IDX            1000          3            100  
    复制代码

    分析数据分析

    (HEIGHT)这个所引高度是,(NAME)索引名为MY_BIT_IDX  ,(LF_ROWS)所引表有1000行数据,(LF_BLKS)占用3个块,(DEL_LF_ROWS)删除100条记录。

      这里也验证了前面所说的一个问题,删除的100条数据只是标记为删除,因为总的数据条数依然为1000条,占用3个块,那么每个块大于333条记录,只有删除的数据大于333条记录,这时一个块被清空,总的数据条数才会减少。




    在向大家详细介绍Oracle建表之前,首先让大家了解下Oracle索引,因为好的索引能帮助Oracle数据库更好的检索我们想要的信息。

    Oracle索引逻辑上:
    Single column 单行索引
    Concatenated 多行索引
    Unique 唯一索引
    NonUnique 非唯一索引
    Function-based函数索引
    Domain 域索引

    Oracle索引物理上:
    Partitioned 分区索引
    NonPartitioned 非分区索引
    B-tree:
    Normal 正常型B树
    Rever Key 反转型B树
    Bitmap 位图索引

    Oracle索引结构:
    B-tree:
    适合与大量的增、删、改(OLTP);
    不能用包含OR操作符的查询;
    适合高基数的列(唯一值多)
    典型的树状结构;
    每个结点都是数据块;
    大多都是物理上一层、两层或三层不定,逻辑上三层;
    叶子块数据是排序的,从左向右递增;
    在分支块和根块中放的是索引的范围;
    Bitmap:
    适合与决策支持系统;
    做UPDATE代价非常高;
    非常适合OR操作符的查询;
    基数比较少的时候才能建位图索引;
    树型结构:
    索引头
    开始ROWID,结束ROWID(先列出索引的最大范围)
    BITMAP
    每一个BIT对应着一个ROWID,它的值是1还是0,如果是1,表示着BIT对应的ROWID有值;

    B*tree索引的话通常在访问小数据量的情况下比较适用,比如你访问不超过表中数据的5%,当然这只是个相对的比率,适用于一般的情况。bitmap的话在数据仓库中使用较多,用于低基数列,比如性别之类重复值很多的字段,基数越小越好。


    展开全文
  • SQL Server和Oracle数据库索引介绍

    千次阅读 2016-05-25 16:27:38
    SQL Server和Oracle数据库索引介绍 1 SQL Server中的索引   索引是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度。索引包含由表或视图中的一列或多列生成的键。这些键存储在一个结构(B 树)中...

    SQL ServerOracle数据库索引介绍

    1 SQL Server中的索引 

      索引是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度。索引包含由表或视图中的一列或多列生成的键。这些键存储在一个结构(B )中,使 SQL Server 可以快速有效地查找与键值关联的行。

      表或视图可以包含以下类型的索引:

      聚集索引

      聚集索引根据数据行的键值在表或视图中排序和存储这些数据行。索引定义中包含聚集索引列。每个表只能有一个聚集索引,因为数据行本身只能按一个顺序排序。

      只有当表包含聚集索引时,表中的数据行才按排序顺序存储。如果表具有聚集索引,则该表称为聚集表。如果表没有聚集索引,则其数据行存储在一个称为堆的无序结构中。

      每个表几乎都对列定义聚集索引来实现下列功能:

      1、可用于经常使用的查询。

      2、提供高度唯一性。

      在创建聚集索引之前,应先了解数据是如何被访问的。考虑对具有以下特点的查询使用聚集索引:

      使用运算符(BETWEEN>>=< <=)返回一系列值。

      使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行物理相邻。例如,如果某个查询在一系列采购订单号间检索记 录,PurchaseOrderNumber 列的聚集索引可快速定位包含起始采购订单号的行,然后检索表中所有连续的行,直到检索到最后的采购订单号。

      返回大型结果集。

      使用 JOIN 子句;一般情况下,使用该子句的是外键列。

      使用 ORDER BY GROUP BY 子句。

      在 ORDER BY GROUP BY 子句中指定的列的索引,可以使数据库引擎 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。

      聚集索引不适用于具有下列属性的列:

      频繁更改的列

      这将导致整行移动,因为数据库引擎 必须按物理顺序保留行中的数据值。这一点要特别注意,因为在大容量事务处理系统中数据通常是可变的。

      宽键

    宽键是若干列或若干大型列的组合。所有非聚集索引将聚集索引中的键值用作查找键。为同一表定义的任何非聚集索引都将增大许多,这是因为非聚集索引项包含聚集键,同时也包含为此非聚集索引定义的键列。 

    非聚集索引

      非聚集索引具有独立于数据行的结构。非聚集索引包含非聚集索引键值,并且每个键值项都有指向包含该键值的数据行的指针。

      从非聚集索引中的索引行指向数据行的指针称为行定位器。行定位器的结构取决于数据页是存储在堆中还是聚集表中。对于堆,行定位器是指向行的指针。对于聚集表,行定位器是聚集索引键。

      在 SQL Server 2005 中,可以向非聚集索引的叶级别添加非键列以跳过现有的索引键限制(900 字节和 16 键列),并执行完整范围内的索引查询。

      非聚集索引与聚集索引具有相同的 B 树结构,它们之间的显著差别在于以下两点:

      1、基础表的数据行不按非聚集键的顺序排序和存储。

      2、非聚集索引的叶层是由索引页而不是由数据页组成。

      设计非聚集索引时需要注意数据库的特征:

      更新要求较低但包含大量数据的数据库或表可以从许多非聚集索引中获益从而改善查询性能。

      决策支持系统应用程序和主要包含只读数据的数据库可以从许多非聚集索引中获益。查询优化器具有更多可供选择的索引用来确定最快的访问方法,并且数据库的低更新特征意味着索引维护不会降低性能。

      联机事务处理应用程序和包含大量更新表的数据库应避免使用过多的索引。此外,索引应该是窄的,即列越少越好。

      一个表如果建有大量索引会影响 INSERTUPDATE DELETE 语句的性能,因为所有索引都必须随表中数据的更改进行相应的调整。

      唯一索引

      唯一索引确保索引键不包含重复的值,因此,表或视图中的每一行在某种程度上是唯一的。

      聚集索引和非聚集索引都可以是唯一索引。

      包含性列索引

      一种非聚集索引,它扩展后不仅包含键列,还包含非键列。

      索引涵盖

      指查询中的SELECTWHERE子句的所用列同时也属于非聚集索引的情况。这样就可以更快检索数据,因为所有信息都可以直接来自于索引页,从而SQL Server可以避免访问数据页。加上独立的索引文件组,可以用最快速度访问数据。

      请看如下表示例:

      A.创建简单非聚集索引 以下示例为 Purchasing.ProductVendor 表的 VendorID 列创建非聚集索引。 

     

     

      B. 创建简单非聚集组合索引

      以下示例为 Sales.SalesPerson 表的 SalesQuota SalesYTD 列创建非聚集组合索引。 

     

     

      C. 创建唯一非聚集索引

      以下示例为 Production.UnitMeasure 表的 Name 列创建唯一的非聚集索引。该索引将强制插入 Name 列中的数据具有唯一性。 

     

     

      无论何时对基础数据执行插入、更新或删除操作,SQL Server 2005 数据库引擎都会自动维护索引。随着时间的推移,这些修改可能会导致索引中的信息分散在数据库中(含有碎片)。当索引包含的页中的逻辑排序(基于键值)与数 据文件中的物理排序不匹配时,就存在碎片。碎片非常多的索引可能会降低查询性能,导致应用程序响应缓慢。这个时候,我们需要做得就是重新组织和重新生成索 引。重新生成索引将删除该索引并创建一个新索引。此过程中将删除碎片,通过使用指定的或现有的填充因子设置压缩页来回收磁盘空间,并在连续页中对索引行重 新排序(根据需要分配新页)。这样可以减少获取所请求数据所需的页读取数,从而提高磁盘性能。

      可以使用下列方法重新生成聚集索引和非聚集索引:

      带 REBUILD 子句的 ALTER INDEX。此语句将替换 DBCC DBREINDEX 语句。

      带 DROP_EXISTING 子句的 CREATE INDEX

      示例如下:

      A. 重新生成索引 

    以下示例将重新生成单个索引。  

          USE AdventureWorks;
      GO
      ALTER INDEX PK_Employee_EmployeeID ON HumanResources.Employee
      REBUILD;
      GO 


      
    B.重新生成表的所有索引并指定选项

      下面的示例指定了 ALL 关键字。这将重新生成与表相关联的所有索引。其中指定了三个选项。 

          ALTER INDEX ALL ON Production.Product
      REBUILD WITH (FILLFACTOR = 80, SORT_IN_TEMPDB = ON,
      STATISTICS_NORECOMPUTE = ON);
      GO 


          2 Oracle
    中的索引

      索引是Oracle使用的加速表中数据检索的数据库对象。

      下面的情况,可以考虑使用索引:

      1) 大表

      2) 主键(自动索引)

      3) 单键列(自动索引)

      4) 外键列(自动索引)

      5) 大表上WHERE子句常用的列

      6) ORDER BY 或者GROUP BY子句中使用的列。

      7) 至少返回表中20%行的查询

      8) 不包含null值的列。

      Oracle中的索引包含有如下几种类型:

      B*树索引:这是Oracle中最常用的索引,它的构造类似于二叉树,能根据键提供一行或一个行集的快速访问,通常只需要很少的读操作就能找到正确的行。B*树索引由两列组成,第一列是ROWID, 它是行的位置;第二列是正被索引列的值。  

      图:典型的B*树索引布局

      这个树底层的块称为叶子节点(leaf node) (leaf block),其中分别包含各个索引键以及一个rowid(它是指向所索引的行)。叶子节点之上的内部块称为分支块(branch block),这些节点用于实现导航。例如,如果想在索引中找到值20,要从树顶开始,找到左分支,我们检查这个块,并发现需要找到范围"20..25" 的块,这个块将是叶子块,其中会指示包含数20的行。索引的叶子节点实际上构成了一个双向链表。一旦发现要从叶子节点中的那里开始,执行值的有序扫描 (index range scan)就会很容易,我们就不必再在索引结构中导航:而只需根据叶子节点向前或向后扫描就可以了。

      B*树的特点之一是:所有叶子块都应该在树的同一层上,这一层称之为索引的高度, 它说明所有从索引的根块到叶子块的遍历都会访问同样数目的块。也就是说,对于形如"SELECT INDEX_column FROM TABLE WHERE INXDEX_column =:X"的索引,要达到叶子块来获取第一行,不论使用的:X值是什么,都会执行同样数目的I/O,由此可见B*树的B代表的是balanced,所谓的"Height balanced"。大多数B*树索引的高度都是23,即使索引中有数百万行记录也是如此,这说明,一般而言,在索引中找到一个键只需要23I/O , 这确实不错。

      B*树是一个极佳的通用索引机制,无论是大表还是小表都很适用,随着底层表大小增长,获取数据的性能仅会稍有恶化。

      比如,我们为customers表建立一个常见的B*树索引: 

     

     

      B*树索引有以下子类型:

      复合索引

      复合索引也是一种B*树索引,它由多列组成。当我们拥有使用两列或超过两列的频繁查询时,就使用B*树复合索引,而其所使用的两列或多列在 where子句中and逻辑操作符连接。因为复合索引中列的顺序很重要,所以确信以最有效的索引能排列他们,可以参考用作列排序的下面的两个准则 :

      1) 前导列应该是查询中使用最频繁的列。

      2) 前导列应该是选择最多的列,这意味着它比后面的列具有更高的基数。

      复合索引在下列情况中具有优势:

      1)假定在WHERE子句中频繁使用下面的条件:order_status_id = 1 order_date = ‘dd-mon-yyyy’。如果为每一列创建一个索引,那么为了搜索列的值,两个索引都要被读取,但是如果为两列都创建一个复合索引,那么只有一个索引 被读取,这样无疑比两个索引要求更少的I/O

      2) 使用前面例子中同样的条件,如果创建一个复合索引,将更快地检索行,因为你正在排除了所有order_status_id 不是1的行,从而减少了搜索order_date的行数。

      反向键索引

      B*树索引的另一个特点是能够将索引键反转。首先,你可以问问自己为什么想这么做?” B*树索引是为特定的环境、特定的问题而设计的。实现B*树索引的目的是为了减少右侧索引中对索引叶子块的竞争,比如在一个Oracle RAC 环境中,某些列用一个序列值或时间戳填充,这些列上建立的索引就属于右侧”(right-hand-side)索引。

      RAC 是一种Oracle 配置,其中多个实例可以装载和打开同一个数据库。如果两个实例需要同时修改同一个数据块,它们会通过一个硬件互连(interconnect)来回传递这 个块来实现共享,互连是两个(或多个)机器之间的一条专用网络连接。如果某个利用一个序列填充,这个列上有一个主键索引 ,那么每个人插入新值时,都会视图修改目前索引结构右侧的左块(见本文图一,其中显示出索引中较高的值都放在右侧,而较低的值放在左侧)。如果对用序列填 充的列上的索引进行修改,就会聚集在很少的一组叶子块上。倘若将索引的键反转,对索引进行插入时,就能在索引中的所有叶子键上分布开(不过这往往会使索引 不能得到充分地填充)

      反向键索引创建语句语法如下: 

     

     

      降序索引

      降序索引(descending index)oracle 8i引入的,用以扩展B*树索引的功能,它允许在索引中以降序(从大到小的顺序)存储一列。在oracle8i及以上版本中,DESC关键字确实会改变创建和使用索引的的方式。

      我们可以这样创建降序索引

     

     

      位图索引

      位图索引(bitmap index)是从Oracle7.3 版本开始引入的。目前Oracle企业版和个人版都支持位图索引,但标准版不支持。位图索引是为数据仓库/在线分析查询环境设计的,在此所有查询要求的数据在系统实现时根本不知道。位图索引特别不适用于OLTP 系统,如果系统中的数据会由多个并发会话频繁地更新,这种系统也不适用位图索引。

      位图索引是这样一种结构,其中用一个索引键条目存储指向多行的指针;这与B*树结构不同,在B*树结构中,索引键和表中的行存在着对应关系。在位图索引中,可能只有很少的索引条目,每个索引条目指向多行。而在传统的B*树中,一个索引条目就指向一行。

      B*树索引一般来讲应当是选择性的。与之相反,位图索引不应是选择性的,一般来讲它们应该没有选择性。如果有大量在线分析查询,特别是查询 以一种即席方式引用了多列或者会生成诸如COUNT 之类的聚合,在这样的环境中,位图索引就特别有用 。位图索引使用 CREATE BITMAP INDEX index_name ON table_name(column_name1,column_name2) TABLESPACE tablespace_name命令语法创建。

     

     

     

     

    SQL Server查询优化技术及索引

    From: http://www.cnblogs.com/lovewindy/archive/2005/02/19/105959.html

     

    在《数据库原理》里面,对聚簇索引的解释是:聚簇索引的顺序就是数据的物理存储顺序,而对非聚簇索引的解释是:索引顺序与数据物理排列顺序无关。正式因为如此,所以一个表最多只能有一个聚簇索引。

    不过这个定义太抽象了。在SQL Server中,索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。如下图:

     
    非聚簇索引 

     

     
    聚簇索引 


    聚簇索引与非聚簇索引的本质区别到底是什么?什么时候用聚簇索引,什么时候用非聚簇索引? 

    这是一个很复杂的问题,很难用三言两语说清楚。我在这里从SQL Server索引优化查询的角度简单谈谈(如果对这方面感兴趣的话,可以读一读微软出版的《Microsoft SQL Server 2000数据库编程》第3单元的数据结构引论以及第61314单元)


    一、索引块与数据块的区别 

    大家都知道,索引可以提高检索效率,因为它的二叉树结构以及占用空间小,所以访问速度块。让我们来算一道数学题:如果表中的一条记录在磁盘上占用1000字节的话,我们对其中10字节的一个字段建立索引,那么该记录对应的索引块的大小只有10字节。我们知道,SQL Server的最小空间分配单元是页(Page,一个页在磁盘上占用8K空间,那么这一个页可以存储上述记录8条,但可以存储索引800条。现在我们要从一个有8000条记录的表中检索符合某个条件的记录,如果没有索引的话,我们可能需要遍历8000×1000字节/8K字节=1000个页面才能够找到结果。如果在检索字段上有上述索引的话,那么我们可以在8000×10字节/8K字节=10个页面中就检索到满足条件的索引块,然后根据索引块上的指针逐一找到结果数据块,这样IO访问量要少的多。


    二、索引优化技术 

    是不是有索引就一定检索的快呢?答案是否。有些时候用索引还不如不用索引快。比如说我们要检索上述表中的所有记录,如果不用索引,需要访问8000×1000字节/8K字节=1000个页面,如果使用索引的话,首先检索索引,访问8000×10字节/8K字节=10个页面得到索引检索结果,再根据索引检索结果去对应数据页面,由于是检索所有数据,所以需要再访问8000×1000字节/8K字节=1000个页面将全部数据读取出来,一共访问了1010个页面,这显然不如不用索引快。

    SQL Server内部有一套完整的数据检索优化技术,在上述情况下,SQL Server的查询计划(Search Plan)会自动使用表扫描的方式检索数据而不会使用任何索引。那么SQL Server是怎么知道什么时候用索引,什么时候不用索引的呢?SQL Server除了日常维护数据信息外,还维护着数据统计信息,下图是数据库属性页面的一个截图:

     

    从图中我们可以看到,SQL Server自动维护统计信息,这些统计信息包括数据密度信息以及数据分布信息,这些信息帮助SQL Server决定如何制定查询计划以及查询是是否使用索引以及使用什么样的索引(这里就不再解释它们到底如何帮助SQL Server建立查询计划的了)。我们还是来做个实验。建立一张表:tabTest(ID, unqValueintValue),其中ID是整形自动编号主索引,unqValueuniqueidentifier类型,在上面建立普通索引,intValue 是整形,不建立索引。之所以挂上一个没有索引的intValue字段,就是防止SQL Server使用索引覆盖查询优化技术,这样实验就起不到作用了。向表中录入10000条随机记录,代码如下: 

     

     CREATE TABLE [dbo].[tabTest] (
      
    [ID] [int] IDENTITY (11NOT NULL ,
      
    [unqValue] [uniqueidentifier] NOT NULL ,
      
    [intValue] [int] NOT NULL 
     ) 
    ON [PRIMARY]
     
    GO
     
     
    ALTER TABLE [dbo].[tabTest] WITH NOCHECK ADD 
      
    CONSTRAINT [PK_tabTest] PRIMARY KEY  CLUSTERED 
      (
       
    [ID]
      )  
    ON [PRIMARY] 
     
    GO
     
     
    ALTER TABLE [dbo].[tabTest] ADD 
      
    CONSTRAINT [DF_tabTest_unqValue] DEFAULT (newid()) FOR [unqValue]
     
    GO
     
     
    CREATE  INDEX [IX_tabTest_unqValue] ON [dbo].[tabTest]([unqValue]ON [PRIMARY]
     
    GO
     
     
    declare @i int
     
    declare @v int
     
     
    set @i=0
     
    while @i<10000
     
    begin
         
    set @v=rand()*1000    
         
    insert into tabTest ([intValue]values (@v)
         
    set @i=@i+1
     
    end
     
     

     

    然后我们执行两个查询并查看执行计划,如图:(在查询分析器的查询菜单中可以打开查询计划,同时图上第一个查询的GUID是我从数据库中找的,大家做实验的时候可以根据自己数据库中的值来定):

     

    从图中可以看出,在第一个查询中,
    SQL Server使用了IX_tabTest_unqValue索引,根据箭头方向,计算机先在索引范围内找,找到后,使用Bookmark Lookup将索引节点映射到数据节点上,最后给出SELECT结果。在第二个查询中,系统直接遍历表给出结果,不过它使用了聚簇索引,为什么呢?不要忘了,聚簇索引的页节点就是数据节点!这样使用聚簇索引会更快一些(不受数据删除、更新留下的存储空洞的影响,直接遍历数据是要跳过这些空洞的)。 

    下面,我们在SQL Server中将ID字段的聚簇索引更改为非聚簇索引,然后再执行select * from tabTest,这回我们看到的执行计划变成了:

     

    SQL Server没有使用任何索引,而是直接执行了Table Scan,因为只有这样,检索效率才是最高的。


    三、聚簇索引与非聚簇索引的本质区别 

    现在可以讨论聚簇索引与非聚簇索引的本质区别了。正如本文最前面的两个图所示,聚簇索引的叶节点就是数据节点,而非聚簇索引的页节点仍然是索引检点,并保留一个链接指向对应数据块。

    还是通过一道数学题来看看它们的区别吧:假设有一8000条记录的表,表中每条记录在磁盘上占用1000字节,如果在一个10字节长的字段上建立非聚簇索引主键,需要二叉树节点16000个(这16000个节点中有8000个叶节点,每个页节点都指向一个数据记录),这样数据将占用8000×1000字节/8K字节=1000个页面;索引将占用16000个节点×10字节/8K字节=20个页面,共计1020个页面。

    同样一张表,如果我们在对应字段上建立聚簇索引主键,由于聚簇索引的页节点就是数据节点,所以索引节点仅有8000个,占用10个页面,数据仍然占有1000个页面。

    下面我们看看在执行插入操作时,非聚簇索引的主键为什么比聚簇索引主键要快。主键约束要求主键不能出现重复,那么SQL Server是怎么知道不出现重复的呢?唯一的方法就是检索。对于非聚簇索引,只需要检索20个页面中的16000个节点就知道是否有重复,因为所有主键键值在这16000个索引节点中都包含了。但对于聚簇索引,索引节点仅仅包含了8000个中间节点,至于会不会出现重复必须检索另外1000个页数据节点才知道,那么相当于检索10+1000=1010个页面才知道是否有重复。所以聚簇索引主键的插入速度要比非聚簇索引主键的插入速度慢很多。

    让我们再来看看数据检索的效率,如果对上述两表进行检索,在使用索引的情况下(有些时候SQL Server执行计划会选择不使用索引,不过我们这里姑且假设一定使用索引),对于聚簇索引检索,我们可能会访问10个索引页面外加1000个数据页面得到结果(实际情况要比这个好),而对于非聚簇索引,系统会从20个页面中找到符合条件的节点,再映射到1000个数据页面上(这也是最糟糕的情况),比较一下,一个访问了1010个页面而另一个访问了1020个页面,可见检索效率差异并不是很大。所以不管非聚簇索引也好还是聚簇索引也好,都适合排序,聚簇索引仅仅比非聚簇索引快一点。


    结语 

    好了,写了半天,手都累了。关于聚簇索引与非聚簇索引效率问题的实验就不做了,感兴趣的话可以自己使用查询分析器对查询计划进行分析。SQL Server是一个很复杂的系统,尤其是索引以及查询优化技术,Oracle就更复杂了。了解索引以及查询背后的事情不是什么坏事,它可以帮助我们更为深刻的了解我们的系统。

     

     

    SQL Server基础知识之:设计和实现视图 

    设计和实现视图可谓是数据库物理设计中的一个非常重要的步骤。从一般意义上说,设计和实现视图应该遵循下面的一些建议和原则。

    以下内容摘在文档,我对某些重点进行了补充说明(红色部分)

    ï  只能在当前数据库中创建视图。 但是,如果使用分布式查询定义视图,则新视图所引用的表和视图可以存在于其他数据库甚至其他服务器中。 

    • 分布式视图是可行的,但随着SQL Server本身能力的提高,例如SQL Server 2005开始支持表分区等技术之后,分布式视图应该尽量少用。 
    • 所谓分布式视图的一个最大的问题就是将表物理上分开在多个数据库甚至服务器中,这增加了维护和查询的难度 

    ï  视图名称必须遵循标识符的规则,且对每个架构都必须唯一。 此外,该名称不得与该架构包含的任何表的名称相同。 

    • 一个可以借鉴的做法是:在视图名称之前添加一个前缀 vw 

    ï  您可以对其他视图创建视图。Microsoft SQL Server 允许嵌套视图。但嵌套不得超过 32 层。 根据视图的复杂性及可用内存,视图嵌套的实际限制可能低于该值。 

    • 一般不建议超过2 

    ï  不能将规则或 DEFAULT 定义与视图相关联。 

    ï  不能将 AFTER 触发器与视图相关联,只有 INSTEAD OF 触发器可以与之相关联。 

    • 除非万不得已,一般不建议使用触发器 

    ï  定义视图的查询不能包含 COMPUTE 子句、COMPUTE BY 子句或 INTO 关键字。 

    • 很多朋友不知道:COMPUTERCOMPUTER BY语句仅仅用于一些特殊场合,用于生成总计行。大致有如下的效果 

     

    该特性不能用于视图,但可以直接用于查询

     

    ï  定义视图的查询不能包含 ORDER BY 子句,除非在 SELECT 语句的选择列表中还有一个 TOP 子句。 

    • 这个很有意思,如果要访问所有的呢,还必须是写TOP 100 PERCENT 

    ï  定义视图的查询不能包含指定查询提示的 OPTION 子句。 

    ï  定义视图的查询不能包含 TABLESAMPLE 子句。 

    • 关于TABLESAMPLE语句,大家可能也比较陌生,这是一个用于对数据进行抽样的。它和TOP语句不同,TOP语句是有固定大小的,而TABLESAMPLE返回的数据,可能多,可能少,甚至可能没有 
    • 我之前有一篇文章讲述这个语法 http://www.cnblogs.com/chenxizhang/archive/2009/05/19/1460040.html 

    ï  不能为视图定义全文索引定义。 

    ï  不能创建临时视图,也不能对临时表创建视图。 

    • SQL Server 2005中,可以通过CTECommon Table Expression)来实现该功能 
    • 之前的版本,大致的做法是使用临时表,表变量,函数等等 

    ï  不能删除参与到使用 SCHEMABINDING 子句创建的视图中的视图、表或函数,除非该视图已被删除或更改而不再具有架构绑定。 另外,如果对参与具有架构绑定的视图的表执行 ALTER TABLE 语句,而这些语句又会影响该视图的定义,则这些语句将会失败。 

    • 如果未使用 SCHEMABINDING 子句创建视图,则对视图下影响视图定义的对象进行更改时,应运行 sp_refreshview。 否则,当查询视图时,可能会生成意外结果。 
    • 强烈建议对某些非常重要的视图,添加SCHEMABINDING 子句。 

     

    ï  尽管查询引用一个已配置全文索引的表时,视图定义可以包含全文查询,仍然不能对视图执行全文查询。 

    ï  下列情况下必须指定视图中每列的名称: 

    • 视图中的任何列都是从算术表达式、内置函数或常量派生而来。 
    • 视图中有两列或多列原应具有相同名称(通常由于视图定义包含联接,因此来自两个或多个不同表的列具有相同的名称)。 
    • 希望为视图中的列指定一个与其源列不同的名称。 (也可以在视图中重命名列。) 无论重命名与否,视图列都会继承其源列的数据类型。 

    若要创建视图,您必须获取由数据库所有者授予的此操作执行权限,如果使用 SCHEMABINDING 子句创建视图,则必须对视图定义中引用的任何表或视图具有相应的权限。 

    默认情况下,由于行通过视图进行添加或更新,当其不再符合定义视图的查询的条件时,它们即从视图范围中消失。 例如,创建一个定义视图的查询,该视图从表中检索员工的薪水低于 $30,000 的所有行。如果员工的薪水涨到 $32,000,因其薪水不符合视图所设条件,查询时视图不再显示该特定员工。 但是,WITH CHECK OPTION 子句强制所有数据修改语句均根据视图执行,以符合定义视图的 SELECT 语句中所设条件。 如果使用该子句,则对行的修改不能导致行从视图中消失。 任何可能导致行消失的修改都会被取消,并显示错误。

     

     

     

     

     

     

     

     

     

     

     

    本文由作者:陈希章2009/6/15 17:31:29 发布在:http://www.cnblogs.com/chenxizhang/
    本文版权归作者所有,可以转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    更多博客文章,以及作者对于博客引用方面的完整声明以及合作方面的政策,请参考以下站点:陈希章的博客中心
     

     

    绿色通道:好文要顶关注我收藏该文与我联系  

    RockYang
    关注 - 6
    粉丝 - 10

    +加关注

    0

    0

    (请您对文章做出评价)

    « 博主前一篇:Web Service
    »
    博主后一篇:[]细说Sql Server中的视图

    posted on 2009-12-09 14:48 RockYang 阅读(5330) 评论(5) 编辑 收藏


    FeedBack: 


    #1[楼主] 2009-12-09 15:20 RockYang      

    浅谈数据库索引
    数据库索引是为了增加查询速度而对表字段附加的一种标识。见过很多人机械的理解索引的概念,认为增加索引只有好处没有坏处。这里想把之前的索引学习笔记总结一下:
    首先明白为什么索引会增加速度,DB在执行一条Sql语句的时候,默认的方式是根据搜索条件进行全表扫描,遇到匹配条件的就加入搜索结果集 合。如果我们对某一字段增加索引,查询时就会先去索引列表中一次定位到特定值的行数,大大减少遍历匹配的行数,所以能明显增加查询的速度。那么在任何时候 都应该加索引么?这里有几个反例:1、如果每次都需要取到所有表记录,无论如何都必须进行全表扫描了,那么是否加索引也没有意义了。2、对非唯一的字段, 例如性别这种大量重复值的字段,增加索引也没有什么意义。3、对于记录比较少的表,增加索引不会带来速度的优化反而浪费了存储空间,因为索引是需要存 储空间的,而且有个致命缺点是对于update/insert/delete的每次执行,字段的索引都必须重新计算更新。

    那么在什么时候适合加上索引呢?我们看一个Mysql手册中举的例子,这里有一条sql语句:

    SELECT c.companyID, c.companyName FROM Companies c, User u WHERE c.companyID = u.fk_companyID AND c.numEmployees >= 0 AND c.companyName LIKE '%i%' AND u.groupID IN (SELECT g.groupID FROM Groups g WHERE g.groupLabel = 'Executive')

    这条语句涉及3个表的联接,并且包括了许多搜索条件比如大小比较,Like匹配等。在没有索引的情况下Mysql需要执行的扫描行数是 77721876行。而我们通过在companyIDgroupLabel两个字段上加上索引之后,扫描的行数只需要134行。在Mysql中可以通过 Explain Select来查看扫描次数。可以看出来在这种联表和复杂搜索条件的情况下,索引带来的性能提升远比它所占据的磁盘空间要重要得多。



    那么索引是如何实现的呢?大多数DB厂商实现索引都是基于一种数据结构——B树。因为B树的特点就是适合在磁盘等直接存储设备上组织动态查找表。B树的定义是这样的:一棵m(m>=3)阶的B树是满足下列条件的m叉树:

    1
    、每个结点包括如下作用域(j, p0, k1, p1, k2, p2, ... ki, pi) 其中j是关键字个数,p是孩子指针

    2
    、所有叶子结点在同一层上,层数等于树高h

    3
    、每个非根结点包含的关键字个数满足[m/2-1]<=j<=m-1

    4
    、若树非空,则根至少有1个关键字,若根非叶子,则至少有2棵子树,至多有m棵子树

    看一个B树的例子,针对26个英文字母的B树可以这样构造:



    可以看到在这棵B树搜索英文字母复杂度只为o(m),在数据量比较大的情况下,这样的结构可以大大增加查询速 度。然而有另外一种数据结构查询的虚度比B树更快——散列表。Hash表的定义是这样的:设所有可能出现的关键字集合为u,实际发生存储的关键字记为k, 而|k||u|小很多。散列方法是通过散列函数hu映射到表T[0,m-1]的下标上,这样u中的关键字为变量,以h为函数运算结果即为相应结点的存 储地址。从而达到可以在o(1)的时间内完成查找。
    然而散列表有一个缺陷,那就是散列冲突,即两个关键字通过散列函数计算出了相同的结果。设mn分别表示散列表的长度和填满的结点数,n/m为散列表的填装因子,因子越大,表示散列冲突的机会越大。
    因 为有这样的缺陷,所以数据库不会使用散列表来做为索引的默认实现,Mysql宣称会根据执行查询格式尝试将基于磁盘的B树索引转变为和合适的散列索引以追 求进一步提高搜索速度。我想其它数据库厂商也会有类似的策略,毕竟在数据库战场上,搜索速度和管理安全一样是非常重要的竞争点

     回复 引用 查看 
       

    #2[楼主] 2009-12-09 15:22 RockYang      

     
     回复 引用 查看 
       

    #3[楼主] 2009-12-09 15:42 RockYang      

    据库的查询优化技术

    数据库系统是管理信息系统的核心,基于数据库的联机事务处理(OLTP)以及联机分析处理(OLAP)是银行、企业、政府等部门最为重要的计算机应用之一。从大多数系统的应用实例来看,查询操作在各种数据库操作中所占据的比重最大,而查询操作所基于的SELECT语句在SQL语句中又是代价最大的语句。举例来说,如果数据的量积累到一定的程度,比如一个银行的账户数据库表信息积累到上百万甚至上千万条记录,全表扫描一次往往需要数十分钟,甚至数小时。如果采用比全表扫描更好的查询策略,往往可以使查询时间降为几分钟,由此可见查询优化技术的重要性。
    笔者在应用项目的实施中发现,许多程序员在利用一些前端数据库开发工具(如PowerBuilderDelphi等)开发数据库应用程序时,只注重用户界面的华丽,并不重视查询语句的效率问题,导致所开发出来的应用系统效率低下,资源浪费严重。因此,如何设计高效合理的查询语句就显得非常重要。本文以应用实例为基础,结合数据库理论,介绍查询优化技术在现实系统中的运用。
    分析问题
    许多程序员认为查询优化是DBMS(数据库管理系统)的任务,与程序员所编写的SQL语句关系不大,这是错误的。一个好的查询计划往往可以使程序性能提高数十倍。查询计划是用户所提交的SQL语句的集合,查询规划是经过优化处理之后所产生的语句集合。DBMS处理查询计划的过程是这样的:在做完查询语句的词法、语法检查之后,将语句提交给DBMS的查询优化器,优化器做完代数优化和存取路径的优化之后,由预编译模块对语句进行处理并生成查询规划,然后在合适的时间提交给系统处理执行,最后将执行结果返回给用户。在实际的数据库产品(OracleSybase)的高版本中都是采用基于代价的优化方法,这种优化能根据从系统字典表所得到的信息来估计不同的查询规划的代价,然后选择一个较优的规划。虽然现在的数据库产品在查询优化方面已经做得越来越好,但由用户提交的SQL语句是系统优化的基础,很难设想一个原本糟糕的查询计划经过系统的优化之后会变得高效,因此用户所写语句的优劣至关重要。系统所做查询优化我们暂不讨论,下面重点说明改善用户查询计划的解决方案。
    解决问题
    下面以关系数据库系统Informix为例,介绍改善用户查询计划的方法。
    1
    .合理使用索引
    索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构。索引的使用要恰到好处,其使用原则如下:
    在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。
    在频繁进行排序或分组(即进行group byorder by操作)的列上建立索引。
    在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比如在雇员表的性别列上只有两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。
    如果待排序的列有多个,可以在这些列上建立复合索引(compound index)。
    使用系统工具。如Informix数据库有一个tbcheck工具,可以在可疑的索引上进行检查。在一些数据库服务器上,索引可能失效或者因为频繁操作而使得读取效率降低,如果一个使用索引的查询不明不白地慢下来,可以试着用tbcheck工具检查索引的完整性,必要时进行修复。另外,当数据库表更新大量数据后,删除并重建索引可以提高查询速度。
    2
    .避免或简化排序
    应当简化或避免对大型表进行重复的排序。当能够利用索引自动以适当的次序产生输出时,优化器就避免了排序的步骤。以下是一些影响因素:
    索引中不包括一个或几个待排序的列;
    ●group by
    order by子句中列的次序与索引的次序不一样;
    排序的列来自不同的表。
    为了避免不必要的排序,就要正确地增建索引,合理地合并数据库表(尽管有时可能影响表的规范化,但相对于效率的提高是值得的)。如果排序不可避免,那么应当试图简化它,如缩小排序的列的范围等。
    3
    .消除对大型表行数据的顺序存取
    在嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响。比如采用顺序存取策略,一个嵌套3层的查询,如果每层都查询1000行,那么这个查询就要查询10亿行数据。避免这种情况的主要方法就是对连接的列进行索引。例如,两个表:学生表(学号、姓名、年龄……)和选课表(学号、课程号、成绩)。如果两个表要做连接,就要在学号这个连接字段上建立索引。
    还可以使用并集来避免顺序存取。尽管在所有的检查列上都有索引,但某些形式的where子句强迫优化器使用顺序存取。下面的查询将强迫对orders表执行顺序操作:
    SELECT
    FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008
    虽然在customer_numorder_num上建有索引,但是在上面的语句中优化器还是使用顺序存取路径扫描整个表。因为这个语句要检索的是分离的行的集合,所以应该改为如下语句:
    SELECT
    FROM orders WHERE customer_num=104 AND order_num>1001
    UNION
    SELECT
    FROM orders WHERE order_num=1008
    这样就能利用索引路径处理查询。
    4
    .避免相关子查询
    一个列的标签同时在主查询和where子句中的查询中出现,那么很可能当主查询中的列值改变之后,子查询必须重新查询一次。查询嵌套层次越多,效率越低,因此应当尽量避免子查询。如果子查询不可避免,那么要在子查询中过滤掉尽可能多的行。
    5
    .避免困难的正规表达式
    MATCHES
    LIKE关键字支持通配符匹配,技术上叫正规表达式。但这种匹配特别耗费时间。例如:SELECT FROM customer WHERE zipcode LIKE “98_ _ _”
    即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如果把语句改为SELECT FROM customer WHERE zipcode >“98000”,在执行查询时就会利用索引来查询,显然会大大提高速度。
    另外,还要避免非开始的子串。例如语句:SELECT FROM customer WHERE zipcode[23] >“80”,在where子句中采用了非开始子串,因而这个语句也不会使用索引。

     回复 引用 查看 
       

    #4[楼主] 2009-12-09 15:42 RockYang      

    6.使用临时表加速查询
    把表的一个子集进行排序并创建临时表,有时能加速查询。它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作。例如:
    SELECT cust.name
    rcvbles.balance……other columns
    FROM cust
    rcvbles
    WHERE cust.customer_id = rcvlbes.customer_id
    AND rcvblls.balance>0
    AND cust.postcode>“98000”
    ORDER BY cust.name
    如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个临时文件中,并按客户的名字进行排序:
    SELECT cust.name
    rcvbles.balance……other columns
    FROM cust
    rcvbles
    WHERE cust.customer_id = rcvlbes.customer_id
    AND rcvblls.balance>0
    ORDER BY cust.name
    INTO TEMP cust_with_balance
    然后以下面的方式在临时表中查询:
    SELECT
    FROM cust_with_balance
    WHERE postcode>“98000”
    临时表中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查询工作量可以得到大幅减少。
    注意:临时表创建后不会反映主表的修改。在主表中数据频繁修改的情况下,注意不要丢失数据。
    7
    .用排序来取代非顺序存取
    非顺序磁盘存取是最慢的操作,表现在磁盘存取臂的来回移动。SQL语句隐藏了这一情况,使得我们在写应用程序时很容易写出要求存取大量非顺序页的查询。
    有些时候,用数据库的排序能力来替代非顺序的存取能改进查询。

    实例分析

    下面我们举一个制造公司的例子来说明如何进行查询优化。制造公司数据库中包括3个表,模式如下所示:
    1
    part
    零件号零件描述其他列
    part_numpart_descother column
    102
    032Seageat 30G disk……
    500
    049Novel 10M network card……
    ……
    2
    vendor
    厂商号厂商名其他列
    vendor _numvendor_name) (other column
    910
    257Seageat Corp……
    523
    045IBM Corp……
    ……
    3
    parven
    零件号厂商号零件数量
    part_numvendor_numpart_amount
    102
    0329102573,450,000
    234
    4233210014000000
    ……
    下面的查询将在这些表上定期运行,并产生关于所有零件数量的报表:
    SELECT part_desc
    vendor_namepart_amount
    FROM part
    vendorparven
    WHERE part.part_num=parven.part_num
    AND parven.vendor_num = vendor.vendor_num
    ORDER BY part.part_num
    如果不建立索引,上述查询代码的开销将十分巨大。为此,我们在零件号和厂商号上建立索引。索引的建立避免了在嵌套中反复扫描。关于表与索引的统计信息如下:
    行尺寸行数量每页行数量数据页数量
    table(row size)Row countRows/PagesData Pages
    part15010
    00025400
    Vendor1501
    000 2540
    Parven13 15
    000300 50
    索引键尺寸每页键数量页面数量
    Indexes(Key Size)Keys/Page)(Leaf Pages
    part450020
    Vendor45002
    Parven825060
    看起来是个相对简单的3表连接,但是其查询开销是很大的。通过查看系统表可以看到,在part_num上和vendor_num上有簇索引,因此索引是按照物理顺序存放的。parven表没有特定的存放次序。这些表的大小说明从缓冲页中非顺序存取的成功率很小。此语句的优化查询规划是:首先从part中顺序读取400页,然后再对parven表非顺序存取1万次,每次2页(一个索引页、一个数据页),总计2万个磁盘页,最后对vendor表非顺序存取1.5万次,合3万个磁盘页。可以看出在这个索引好的连接上花费的磁盘存取为5.04万次。
    实际上,我们可以通过使用临时表分3个步骤来提高查询效率:
    1
    .从parven表中按vendor_num的次序读数据:
    SELECT part_num
    vendor_numprice
    FROM parven
    ORDER BY vendor_num
    INTO temp pv_by_vn
    这个语句顺序读parven50页),写一个临时表(50页),并排序。假定排序的开销为200页,总共是300页。
    2
    .把临时表和vendor表连接,把结果输出到一个临时表,并按part_num排序:
    SELECT pv_by_vn
    ,* vendor.vendor_num
    FROM pv_by_vn
    vendor
    WHERE pv_by_vn.vendor_num=vendor.vendor_num
    ORDER BY pv_by_vn.part_num
    INTO TMP pvvn_by_pn
    DROP TABLE pv_by_vn
    这个查询读取pv_by_vn(50),它通过索引存取vendor1.5万次,但由于按vendor_num次序排列,实际上只是通过索引顺序地读vendor表(402=42页),输出的表每页约95行,共160页。写并存取这些页引发5160=800次的读写,索引共读写892页。
    3
    .把输出和part连接得到最后的结果:
    SELECT pvvn_by_pn.
    *,part.part_desc
    FROM pvvn_by_pn
    part
    WHERE pvvn_by_pn.part_num=part.part_num
    DROP TABLE pvvn_by_pn
    这样,查询顺序地读pvvn_by_pn(160),通过索引读part1.5万次,由于建有索引,所以实际上进行1772次磁盘读写,优化比例为301。笔者在Informix Dynamic Sever上做同样的实验,发现在时间耗费上的优化比例为51(如果增加数据量,比例可能会更大)



    20
    %的代码用去了80%的时间,这是程序设计中的一个著名定律,在数据库应用程序中也同样如此。我们的优化要抓住关键问题,对于数据库应用程序来说,重点在于SQL的执行效率。查询优化的重点环节是使得数据库服务器少从磁盘中读数据以及顺序读页而不是非顺序读页。


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ponydph/archive/2008/03/08/2158633.aspx
     回复 引用 查看 
       

    #5[楼主] 2009-12-09 15:43 RockYang      

    SQL Server中如何快速获取表的记录总数

    在数据库应用的设计中,我们往往会需要获取某些表的记录总数,用于判断表的记录总数是否过大,是否需要备份数据等。我们通常的做法是:select count(*) as c from tableA 。然而对于记录数巨大的表,上述做法将会非常耗时。在DELL 4400 服务器上做试验,MS Sqlserver 2000 数据库对于100万记录的简单数据表执行上述语句,时间在1分钟以上。如果在表的某个字段上做聚簇索引,第一次执行该语句的时间和没有索引的时间差不多,之后执行上述语句,速度很快,在1秒中以内,但当表的记录数发生较大变化后,再执行该语句又会经历一次耗时的过程。而且不是每个表都适合做聚簇索引的,对于数量巨大的表,如果需要经常增删操作,建聚簇索引是一个很不明智的做法,将会极大的影响增删的速度。那么有没有一个比较简单的方法快速获取表的记录总数呢?答案是有的。

    MS SQL 数据库中每个表都在sysindexes 系统表中拥有至少一条记录,该记录中的rows 字段会定时记录表的记录总数。

    下面是sysindexes 表的相关记录的含义:

    列名 数据类型 描述

    id int
    ID(如果 indid = 0 255)。否则为索引所属表的ID

    Indid smallint
    索引ID

    0
    =表

    1
    =聚簇索引

    >1
    =非聚簇索引

    255
    =具有textimage数据的表条目。

    rows int
    基于indid=0 indid=1地数据级行数,该值对于indid>1重 复。如果indid=255rows设置为0



    当表没有聚簇索引时,Indid = 0 否则为 1


    那么现在大家应该知道如何获取表的记录总数了,只需执行如下语句:

    select rows from sysindexes where id = object_id(tablename) and indid in (0,1)


    该方法获取表的记录总数的速度非常快,在毫秒级就可以完成,相比select count(*) 要快上数万倍,但是大家在运用该方法是一定要主要,该方法得到的表的总记录数不是一个精确值,原因是MS SQL 并不是实时更新该字段的值,而是定时更新,当从实践来看该值和精确值一般误差不大,如果你希望快速的粗略估算表的大小,建议你采用该方法。如果你希望得到精确值,那么请在执行上述语句前执行DBCC UpdateUSAGE(DatabaseName,[TABLENAME]) WITH ROW_COUNTS 强制更新该字段的值,但这样第一次更新时会耗费大量的时间,这样做的效果和建有聚簇索引的表 select count (*) 效果相差不大,所以如果你希望相对快速地得到精确的表的记录总数,那么你有两种选择,建聚簇索引或者先DBCC 再使用上述方法。 

    展开全文
  • Oracle数据库索引及plsql索引添加

    千次阅读 2018-04-07 13:31:47
    做压力测试的时候,领导叫我根据项目里的sql语句在数据库内添加索引,了解了下数据库索引的概念及在plsql中的索引添加方法。索引是对表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息...

    做压力测试的时候,领导叫我根据项目里的sql语句在数据库内添加索引,了解了下数据库索引的概念及在plsql中的索引添加方法。

    索引是对表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息。

    索引的一个主要目的就是加快检索表中数据的方法,亦即能协助信息搜索者尽快的找到符合限制条件的记录ID的辅助数据结构。

    简单来说,就是根据sql语句,对where后的条件,在数据库中加上索引,那么每次搜索的时候会先去索引里面找条件,节省搜索的时间。比如select * from user where name='tom' and age='16' ,那么可以给这一句加上name和age的索引,需要注意的是索引里两个字段的顺序也需要根据where语句后的顺序来。

    那么在plsql图形化界面中添加索引的方法是,选中相应的表右键编辑,上方导航中会有索引选项,点进去后主键是默认为索引的,继续添加你需要的索引即可。


    展开全文
  • oracle数据库索引种类,分别什么情况下使用 关于索引有些地方我不太明白1.oracle常用的都有哪几种索引,比如唯一索引之类的,sql语句都是怎么写?2.都在什么情况下适合用?3.最正常的语句create index name on..........

    oracle数据库索引种类,分别什么情况下使用

    关于索引有些地方我不太明白1.oracle常用的都有哪几种索引,比如唯一索引之类的,sql语句都是怎么写?2.都在什么情况下适合用?3.最正常的语句create index name on.......建出来的是那种索引啊?4.表中主键和外键是不是自动给分配索引,自己就不用建了呢?谢谢
    偶从这路过 | 浏览 7114 次 |举报
    我有更好的答案
    推荐于2017-10-01 07:46:12 最佳答案
    1. b-tree索引
    Oracle数据库中最常见的索引类型是b-tree索引,也就是B-树索引,以其同名的计算科学结构命名。CREATE
    INDEX语句时,默认就是在创建b-tree索引。没有特别规定可用于任何情况。
    2. 位图索引(bitmap index)
    位图索引特定于该列只有几个枚举值的情况,比如性别字段,标示字段比如只有0和1的情况。
    3. 基于函数的索引
    比如经常对某个字段做查询的时候是带函数操作的,那么此时建一个函数索引就有价值了。
    4. 分区索引和全局索引
    这2个是用于分区表的时候。前者是分区内索引,后者是全表索引
    5. 反向索引(REVERSE)
    这个索引不常见,但是特定情况特别有效,比如一个varchar(5)位字段(员工编号)含值
    (10001,10002,10033,10005,10016..)
    这种情况默认索引分布过于密集,不能利用好服务器的并行
    但是反向之后10001,20001,33001,50001,61001就有了一个很好的分布,能高效的利用好并行运算。
    6.HASH索引
    HASH索引可能是访问数据库中数据的最快方法,但它也有自身的缺点。集群键上不同值的数目必须在创建HASH集群之前就要知道。需要在创建HASH集群的时候指定这个值。使用HASH索引必须要使用HASH集群。

    tj_angela 

    采纳率:47% 来自团队:Oracle爱好者 擅长: 历史话题

    其他回答

    问题太多了吧?

    逻辑上:
    Single column 单列索引
    Concatenated 多列索引
    Unique 唯一索引
    NonUnique 非唯一索引
    Function-based函数索引
    Domain 域索引

    物理上:
    Partitioned 分区索引
    NonPartitioned 非分区索引
    B-tree:
    Normal 正常型B树
    Rever Key 反转型B树
    Bitmap 位图索引

    create index name on:就是普通的 非唯一索引 或 函数索引

    主键会给分配索引,外键不会自动分配索引,需要自己创建
     本回答被提问者和网友采纳
    micro0369  | 推荐于2018-02-10 22:02:28
    举报| 评论 
    8 
    展开全文
  • Oracle数据库索引底层实现原理笔记

    千次阅读 2020-08-19 16:49:20
    当然, 有的数据库也使用哈希桶作用索引的数据结构 , 然而, 主流的RDBMS都是把平衡树当做数据表默认的索引数据结构的。 我们平时建表的时候都会为表加上主键, 在某些关系数据库中, 如果建表时不指定主键,...
  • Oracle数据库索引的创建

    千次阅读 2018-09-12 19:00:18
    数据库建立的时候 如果表数据和索引数据不需要分开  建表时直接指定主键索引  CREATE TABLE VOAMASTM (   "REFCODE" NUMBER(10) DEFAULT 0 NOT NULL ,   "OWNERREFCODE" NUMBER(10) ...
  • 关于oracle数据库索引

    2014-01-14 03:15:11
    执行sql如下: select * from lm3.cc03 ...lm3.cc03表中有aae017和aae036 的组合索引,也有aae036 的单独索引。 但是执行以上sql时,lm3.cc03检索用不上索引,为什么? 哪位大侠给指导一下,谢谢!
  • 如何合理创建Oracle数据库索引的3个要求:  在Oracle数据库中,创建索引虽然比较简单。但是要合理的创建索引则比较困难了。笔者认为,在创建索引时要做到三个适当,即在适当的表上、适当的列上创建适当数量的...
  • 浅谈oracle数据库索引

    千次阅读 2015-03-11 20:39:28
    [什么是索引] 在关系型数据库中,索引是一种和表有关的数据结构,它可以使查询的sql...数据库索引也是一样,只有先插入好数据,再建立索引。 [如何创建索引] 创建表: create table person (id int, sex char(1), na
  • ORACLE数据库索引失效

    千次阅读 2011-04-15 00:07:00
    数据库中有一个表,用PL/SQL查看该表的索引没有被DROP掉,  但是表上的数据查询起来很慢(查询时间大概是原来的3倍),后来重建了一下索引就好了,  请问这是为什么,  在什么情况下会出现类似的索引丢失的...
  • 参考链接 http://blog.itpub.net/14401924/viewspace-659821/
  • Oracle数据库中,创建索引虽然比较简单。但是要合理的创建索引则比较困难了。笔者认为,在创建索引时要做到三个适当,即在适当的表上、适当的列上创建适当数量的索引。虽然这可以通过一句话来概括优化的索引的基本...
  • Oracle 数据库修改索引表空间
  • ORACLE数据库索引类型及其适用场景
  • 一旦建立了索引,在用户表中建立、更改和删除数据库时, Oracle就自动地维护索引。创建索引时,下列准则将帮助用户做出决定:  1) 索引应该在SQL语句的"where"或"and"部分涉及的表列(也称谓词...
  • 数据库索引: 索引有单列索引 复合索引之说 如何某表的某个字段有主键约束和唯一性约束,则Oracle 则会自动在相应的约束列上建议唯一索引。数据库索引主要进行提高访问速度。 建设原则:  1、索引应该经常建在...
  • Oracle数据库添加索引注意事项

    千次阅读 2018-02-05 10:39:40
    1.确定是否有专门的索引空间。 --查看表所在的表空间 SELECT * FROM user_tables t WHERE t.table_name='TABLENAME'; --查看索引所在的索引空间 SELECT TABLESPACE_NAME FROM DBA_INDEXES WHERE INDEX_NAME='...
  • oracle数据库在实时监控sql性能时怎么筛选那些没有索引的,性能差的sql语句,需要实时的,最好能自主选择一段时间的
  • 各种Oracle索引类型介绍 逻辑上: Single column 单行索引 Concatenated 多行索引 Unique 唯一索引 NonUnique 非唯一索引 Function-based函数索引 Domain 域索引 物理上: Partitioned 分区索引 NonPartitioned ...
  • Oracle数据库

    万人学习 2016-12-31 09:04:38
    本课程主要讲解如下内容:Oracle体系结构、Oracle 基础管理、SQL 语言、Sequence和...在本课程讲解之中会提供有相应的练习习题以及综合案例分析,帮助读者迅速掌握Oracle数据库的核心开发技能。官方QQ群:612148723。
  • 一般来说ORACLE索引由系统自动启用的,也可以强制使用,方法如下: /*假如表为Grade_xu 列名为(学号) 索引名为index1*/ --创建索引 create index index1 on Grade_xu(学号); --查询Grade_xu中索引是否创建,...
  • oracle数据库建立索引的原则

    千次阅读 2016-08-08 23:16:02
    数据库建立索引的原则 1,确定针对该表的操作是大量的查询操作还是大量的增删改操作。 2,尝试建立索引来帮助特定的查询。检查自己的sql语句,为那些频繁在where子句中出现的字段建立索引。 3,尝试建立复合索引来...
  • oracle数据库删除索引的正确方式

    千次阅读 2020-06-30 15:52:59
    有时候发现你之前创建的索引后来你用不上了,于是为了节省空间,降低优化器在选择执行计划时候的成本。我们会选择删除这个索引。 但是因为业务场景比较多,又不是所有代码都是一个人写的。所以直接drop索引可能导致...
  • Oracle数据库之视图与索引

    千次阅读 2015-06-22 23:44:25
    Oracle数据库之视图与索引1. 视图简介视图是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改。视图基于的表称为基表,视图是存储在数据字典里的一条SELECT语句。通过...
  • Oracle 数据库对象-索引

    千次阅读 2014-05-31 09:44:27
    数据库索引(Index)的概念与目录的概念非常类似。如果某列出现在查询的条件中, 而该列的数据是无序的,查询时只能从第一行开始一行一行的匹配。创建索引就是对某些特 定列中的数据排序,生成独立的索引表。在...
  • 文章目录一、Oracle 数据库概述1、Oracle 概述二、关系型数据库1、数据库管理系统2、数据库设计范式三、Oracle 11g 的新功能 一、Oracle 数据库概述 1、Oracle 概述 ...可以说Oracle数据库系统是目前世界上...
  • 掌握Oracle索引、视图及序列的基本使用方法。 【实验内容】 1.用hr用户连接数据库后,为EMPLOYEES表的DEPARTMENT_ID列添加索引。 连接后查询索引可知employees表的department_id已有索引 emp_department_id,故...
  • Oracle数据库索引的维护

    千次阅读 2004-08-30 10:08:00
    查看系统表中的用户索引Oracle中,SYSTEM表是安装数据库时自动建立的,它包含数据库的全部数据字典,存储过程、包、函数和触发器的定义以及系统回滚段。一般来说,应该尽量避免在SYSTEM表中存储非SYSTEM用户的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 175,928
精华内容 70,371
关键字:

oracle数据库索引