SQL SERVER有一种聚集索引,整个表的记录会按聚集索引键的顺序物理存储,比如我在日期上建了个聚集索引,那么整个表就按照日期由早到晚来排列,如果我想查询2009.2.1日至2009.2.28日的数据,SQLSERVER会根据索引定位到2009.2.1日第一条记录,然后大片抓取后面的记录,直到遇到一条2009.2.29的为止,后面也不会扫描了,因为必定会大于2009.2.28日。这样我需要1个月的数据,它的I/O量也刚好是一个月,我需要一周的数据,它的I/O量也就是一周。这对于交易表这样随时间增长的案例来说非常好。即使交易档增长到上亿条记录,只要WHERE条件中有日期,I/O量就会相当精确的只抓需要的数据,而不会浪费。但我却没发现ORACLE有这样的索引,ORACLE有一种IOT表,但是它只能根据主键顺序来,但主键是不可重复的,如果需求要以日期来建IOT,日期是有重复值的。请教各位高手,在ORACLE的解决方案是如何?聚集簇和分区能解决这种需求吗?感谢各位!

解决方案 »

  1.   

    回1楼的同学,分区表是固定的,比如按月分的话,一个月的数据是一个区,那我要SELECT 一天的数据,它也要扫描整整一个月的数据块,才能完成。
    但SQL SERVER的聚集索引,却可以只扫描一天的数据块就行。分区太固定,不象SQLSERVER聚集索引那样灵活。
      

  2.   

    对这个mssql里的技术不是很了解,不过看你上面说的意思,和分区表是一样的概念,分区表上的local index应该和你说的是一样的吧
      

  3.   

    不熟悉sqlserver,能举个例子吗?
      

  4.   

    SQL SERVER里的聚集索引,概念有点象ORACLE的IOT表,整个表的物理存储顺序是由小到大来存储,不同的是SQLSERVER是按聚集索引键,ORACLE是按主键,当然每个表的聚集索引只会有一个,因为表的存储顺序只会有一种。
    聚集索引跟普通索引的不同在于,聚集索引的“叶级”就是表本身。根据普通索引查找一条记录,要先找到叶子级,找到记录的指针,再去表中找那条记录。而聚集索引找到了叶子级也就找到记录了,叶子即是表。
    例如,我对入库单表按照“日期”来建立一个聚集索引,整个入库表就是按日期来排列的,日期小的在前面,大的在后面,如下所示:日期         单号  产品  数量
    2008.5.01  0005  螺丝  8
    2008.5.10  0050  轴承  7
    2008.6.01  0114  油漆  10
    2008.6.10  0225  钢管  5
    2008.6.20  0005  螺丝  3
    2008.7.01  0465  钢板  9如果下SQL想抓取6月份上半月的数据,SQL SERVER会先根据索引找到6.1日的第一条记录,然后成片扫描后续的记录,直到出现一条6.16日为止。它跟普通索引的区别在于,普通索引找到一条2008.6.1的记录后,需要根据记录指针再跑到表里去找其他字段,而聚集索引不需要,表即是索引,索引即是表。聚集索引跟表分区在功能上的不同在于,聚集索引更灵活,如果我想抓3个月的数据,他的I/O量就是扫描3个月的,如果我想抓7天的数据,他的I/O就刚好是7天的数据。而分区就不行了,如果我是按月分的,抓7天的数据也会扫描整个分区。
      

  5.   

    3楼和4楼的朋友,你们可以把SQL SERVER的聚集索引完全想象成ORACLE的IOT表,它们的原理是一样的。它和IOT表的唯一不同是,IOT是根据主键来排序的,但聚集索引可以用任何一个字段来排序,这个字段可以有重复值。这是唯一的不同。另外,聚集索引和普通索引的不同,我们用下面一个小例子来说明:    一个入库单表,对日期字段建立聚集索引和普通索引,看它们的区别:
        假设索引有4层,我下SQL想查询2008.6.1-2008.6.15日的入库单,一共有10笔符合条件,
        对于普通索引,它会先根据索引找到2008.6.1的第1笔记录,此时I/O量是4个块,然后记下这10笔记录的指针,再去表中查找每条记录,每条记录的I/O量都是1个块,一共是14个块的I/O量。
        对于聚集索引,它会先根据索引找到2008.6.1的第1笔记录,因为叶子即是表,SQL就能获得其他字段了,然后顺序向下读,后面这10条符合条件的记录都在同一个块上,所以整个I/O量只有4个块。
        这就是聚集索引和普通索引的差别。
      

  6.   

    IOT表......
    index organized table......
    索引组织表......
    索引组织表+分区表=?SQL SERVER的聚集索引?
      

  7.   


    回8楼的同学,基本可以说索引组织表=SQL SERVER的聚集索引。
    两者的唯一区别,索引组织表只能根据主键排序,要求唯一,而聚集索引不需要键唯一。
    例如我想以日期来排序表,SQL SERVER就能实现,而ORACLE想实现的话,可能就必须用日期+序列号字段达到唯一后才行了。
      

  8.   

    Cluster Index, 就是Oracle中的 Index Organized Table (IOT)所谓ClusterIndex 或Oracle IOT, 是指table的row data是按BTree来存储的, 
    然而普通的index, 是不会影响table row data的存储方式.那么ClusterIndex 或Oracle IOT有什么好处呢?
    如果该Table经常用主键 (唯一建) 来访问, 那么访问速度要比普通index快, 并且在存储空间上, 比普通index节省.至于为什么, 请参阅Oracle官方文档Index Organized Table .
    (MSDN太大, 懒得找了...)
      

  9.   

    sql server 聚集索引更新插入可能会很慢,如果结果会改变某行的位置的话.但 select 是相当快的. oracle 中如果数据量不是大得离谱的话,普通表加索引就行,数据量太大再考虑分区表.无论如何要避免全表扫描,多在 sql 上想办法.
      

  10.   

    只要在合适的日期字段上建立索引,当查询某天或者某月或者任意时间段纪录的时候,Oracle是不会蠢到扫描表中的所有数据的。甚至,如果你统计的数据都包含在索引中的话,Oracle甚至都连表都不扫描。
    举例,工资表如下create table salary
    ( employee_name varchar2(64)
    , pay_date      date
    , amount        integer);如果要查询某个时间段的工资总额或者平均值或者whatever,如果在pay_date和amount上建有索引,
    create index idx_salary_1 on salary (pay_date, amount);那么类似的查询只查询这个idx中满足条件的数据块。
    select sum(amount),avg(amount) 
    from salary
    where pay_date between :date1 and :date2;所以,只要索引设计合理,不需要去担心Oracle会做太多的无用功。
      

  11.   

    index organized table就是oracle的聚集索引,而且效率很高.