数据库索引有哪几种,怎样建立索引

数据库索引有哪几种,怎样建立索引,第1张

数据索引的种类:

1、按照索引列值的唯一性,索引可分为唯一索引和非唯一索引

非唯一索引:B树索引

create index 索引名 on 表名(列名) tablespace 表空间名;

唯一索引:建立主键或者唯一约束时会自动在对应的列上建立唯一索引

2、索引列的个数:单列索引和复合索引

3、按照索引列的物理组织方式

B树索引

create index 索引名 on 表名(列名) tablespace 表空间名;

位图索引

create bitmap index 索引名 on 表名(列名) tablespace 表空间名;

反向键索引

create index 索引名 on 表名(列名) reverse tablespace 表空间名;

函数索引

create index 索引名 on 表名(函数名(列名)) tablespace 表空间名;

删除索引

drop index 索引名

重建索引

alter index 索引名 rebuild

索引的创建格式: 

CREATE UNIUQE | BITMAP INDEX <schema><index_name> 

    ON <schema><table_name> 

    (<column_name> | <expression> ASC | DESC, 

     <column_name> | <expression> ASC | DESC,) 

    TABLESPACE <tablespace_name> 

    STORAGE <storage_settings> 

    LOGGING | NOLOGGING 

    COMPUTE STATISTICS 

    NOCOMPRESS | COMPRESS<nn> 

    NOSORT | REVERSE 

    PARTITION | GLOBAL PARTITION<partition_setting>

UNIQUE | BITMAP:指定UNIQUE为唯一值索引,BITMAP为位图索引,省略为B-Tree索引。 

    <column_name> | <expression> ASC | DESC:可以对多列进行联合索引,当为expression时即“基于函数的索引” 

    TABLESPACE:指定存放索引的表空间(索引和原表不在一个表空间时效率更高) 

    STORAGE:可进一步设置表空间的存储参数 

    LOGGING | NOLOGGING:是否对索引产生重做日志(对大表尽量使用NOLOGGING来减少占用空间并提高效率) 

    COMPUTE STATISTICS:创建新索引时收集统计信息 

    NOCOMPRESS | COMPRESS<nn>:是否使用“键压缩”(使用键压缩可以删除一个键列中出现的重复值) 

    NOSORT | REVERSE:NOSORT表示与表中相同的顺序创建索引,REVERSE表示相反顺序存储索引值 

    PARTITION | NOPARTITION:可以在分区表和未分区表上对创建的索引进行分区

使用USER_IND_COLUMNS查询某个TABLE中的相应字段索引建立情况

使用DBA_INDEXES/USER_INDEXES查询所有索引的具体设置情况。

在Oracle中的索引可以分为:B树索引、位图索引、反向键索引、基于函数的索引、簇索引、全局索引、局部索引等,下面逐一讲解:

一、B树索引:

最常用的索引,各叶子节点中包括的数据有索引列的值和数据表中对应行的ROWID,简单的说,在B树索引中,是通过在索引中保存排过续的索引列值与相对应记录的ROWID来实现快速查询的目的。其逻辑结构如图:

  可以保证无论用户要搜索哪个分支的叶子结点,都需要经过相同的索引层次,即都需要相同的I/O次数。

B树索引的创建示例:

create index ind_t on t1(id) ;

注1:索引的针对字段创建的,相同字段不能创建一个以上的索引;

注2:默认的索引是不唯一的,但是也可以加上unique,表示该索引的字段上没有重复值(定义unique约束时会自动创建);

注3:创建主键时,默认在主键上创建了B树索引,因此不能再在主键上创建索引。

二、位图索引:

有些字段中使用B树索引的效率仍然不高,例如性别的字段中,只有“男、女”两个值,则即便使用了B树索引,在进行检索时也将返回接近一半的记录。

所以当字段的基数很低时,需要使用位图索引。(“低”的标准是取值数量 < 行数1%)

位图索引的逻辑结构如上图所示:索引中不再记录rowid和键值,而是将每个值作为一列,用0和1表示该行是否等于该键值(0表示否;1表示是)。其中位图索引的行顺序与原表的行顺序一致,可以在查询数据的过程中对应计算出行的原始物理位置。

位图索引的创建示例:

create bitmap index ind_t on t1(type);

注:位图索引不可能是唯一索引,也不能进行键值压缩。

三、反向键索引:

考虑这个情况:某一字段的值是1-1000顺序排列,建立B树索引后依旧递增,到后来该B数索引不断在后面增加分支,会形成如下如的不对称树:

  反向键索引是一种特殊的B树索引,在存储构造中与B树索引完全相同,但是针对数值时,反向键索引会先反向每个键值的字节,然后对反向后的新数据进行索引。例如输入2008则转换为8002,这样当数值一次增加时,其反向键在大小中的分布仍然是比较平均的。

反向键索引的创建示例:

create index ind_t on t1(id) reverse;

注:键的反转由系统自行完成。对于用户是透明的。

四、基于函数的索引:

有的时候,需要进行如下查询:select from t1 where to_char(date,'yyyy')>'2007';

但是即便在date字段上建立了索引,还是不得不进行全表扫描。在这种情况下,可以使用基于函数的索引。其创建语法如下:

create index ind_t on t1(to_char(date,'yyyy'));

注:简单来说,基于函数的索引,就是将查询要用到的表达式作为索引项。

五、全局索引和局部索引:

这个索引貌似很复杂,其实很简单。总得来说一句话,就是无论怎么分区,都是为了方便管理。

具体索引和表的关系有三种:

1、局部分区索引:分区索引和分区表1对1

2、全局分区索引:分区索引和分区表N对N

3、全局非分区索引:非分区索引和分区表1对N

创建示例:

首先创建一个分区表

create table student

(

stuno number(5),

sname vrvhar2(10),

deptno number(5)

)

partition by hash (deptno)

(

partition part_01 tablespace A1,

partition part_02 tablespace A2

);

创建局部分区索引(1v1):

create index ind_t on student(stuno)

local(

partition part_01 tablespace A2,

partition part_02 tablespace A1

); --local后面可以不加

创建全局分区索引(NvN):

create index ind_t on student(stuno)

global partition by range(stuno)

(

partition p1 values less than(1000) tablespace A1,

partition p2 values less than(maxvalue) tablespace A2

); --只可以进行range分区

创建全局非分区索引(1vN)

create index ind_t on student(stuno) GLOBAL;

MySQL支持很多数据类型,选择合适的数据类型存储数据对性能有很大的影响。通常来说,可以遵循以下一些指导原则:

(1)越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。

(2)简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。在MySQL中,应该用内置的日期和时间数据类型,而不是用字符串来存储时间;以及用整型数据类型存储IP地址。

(3)尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL。在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值。

数据库索引的实现原理

一、概述数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。其实说穿了,索引问题就是一个查找问题。二、索引的原理当我们的业务产生了大量的数据时,查找数据的效率问题也就随之而来,所以我们可以通过为表设置索引,而为表设置索引要付出代价的:一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。

上图展示了一种可能的索引方式。左边是数据表,一共有两列七条记录,最左边的是数据记录的物理地址(注意逻辑上相邻的记录在磁盘上也并不是一定物理相邻的)。为了加快Col2的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在O(log2n)的复杂度内获取到相应数据。索引是建立在数据库表中的某些列的上面。在创建索引的时候,应该考虑在哪些列上可以创建索引,在哪些列上不能创建索引。一般来说,应该在这些列上创建索引:在经常需要搜索的列上,可以加快搜索的速度;在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。创建索引可以大大提高系统的性能第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。第四,在使用分组和排序子句进行数据检索时,同样可以显着减少查询中分组和排序的时间。第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢因为,增加索引也有许多不利的方面。创建索引的弊端第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点:第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。三、索引的类型根据数据库的功能,可以在数据库设计器中创建三种索引:唯一索引、主键索引和聚集索引。唯一索引唯一索引是不允许其中任何两行具有相同索引值的索引。当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在employee表中职员的姓(lname)上创建了唯一索引,则任何两个员工都不能同姓。主键索引数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。聚集索引在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。四、局部性原理与磁盘预读由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘的存取速度往往是主存的几百分分之一,因此为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。这样做的理论依据是计算机科学中着名的局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。程序运行期间所需要的数据通常比较集中。由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及 *** 作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多 *** 作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。五、B树和B+树数据结构1、B树B树中每个节点包含了键值和键值对于的数据对象存放地址指针,所以成功搜索一个对象可以不用到达树的叶节点。成功搜索包括节点内搜索和沿某一路径的搜索,成功搜索时间取决于关键码所在的层次以及节点内关键码的数量。在B树中查找给定关键字的方法是:首先把根结点取来,在根结点所包含的关键字K1,…,kj查找给定的关键字(可用顺序查找或二分查找法),若找到等于给定值的关键字,则查找成功;否则,一定可以确定要查的关键字在某个Ki或Ki+1之间,于是取Pi所指的下一层索引节点块继续查找,直到找到,或指针Pi为空时查找失败。2、B+树B+树非叶节点中存放的关键码并不指示数据对象的地址指针,非也节点只是索引部分。所有的叶节点在同一层上,包含了全部关键码和相应数据对象的存放地址指针,且叶节点按关键码从小到大顺序链接。如果实际数据对象按加入的顺序存储而不是按关键码次数存储的话,叶节点的索引必须是稠密索引,若实际数据存储按关键码次序存放的话,叶节点索引时稀疏索引。B+树有2个头指针,一个是树的根节点,一个是最小关键码的叶节点。所以 B+树有两种搜索方法:一种是按叶节点自己拉起的链表顺序搜索。一种是从根节点开始搜索,和B树类似,不过如果非叶节点的关键码等于给定值,搜索并不停止,而是继续沿右指针,一直查到叶节点上的关键码。所以无论搜索是否成功,都将走完树的所有层。B+ 树中,数据对象的插入和删除仅在叶节点上进行。这两种处理索引的数据结构的不同之处:1、B树中同一键值不会出现多次,并且它有可能出现在叶结点,也有可能出现在非叶结点中。而B+树的键一定会出现在叶结点中,并且有可能在非叶结点中也有可能重复出现,以维持B+树的平衡。2、因为B树键位置不定,且在整个树结构中只出现一次,虽然可以节省存储空间,但使得在插入、删除 *** 作复杂度明显增加。B+树相比来说是一种较好的折中。3、B树的查询效率与键在树中的位置有关,最大时间复杂度与B+树相同(在叶结点的时候),最小时间复杂度为1(在根结点的时候)。而B+树的时候复杂度对某建成的树是固定的。六、B/+Tree索引的性能分析到这里终于可以分析B-/+Tree索引的性能了。上文说过一般使用磁盘I/O次数评价索引结构的优劣。先从B-Tree分析,根据B-Tree的定义,可知检索一次最多需要访问h个节点。数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)。一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。综上所述,用B-Tree作为索引结构效率是非常高的。

格式为:

SELECT 字段名表

FROM 表名表

WITH (INDEX(索引名))

WHERE 查询条件

SQL-索引的作用:

微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered index,也称非聚类索引、非簇集索引)。下面,我们举例来说明一下聚集索引和非聚集索引的区别:

其实,我们的汉语字典的正文本身就是一个聚集索引。比如,我们要查“安”字,就会很自然地翻开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a”开头并以“z”结尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”开头的部分仍然找不到这个字,那么就说明您的字典中没有这个字;同样的,如果查“张”字,那您也会将您的字典翻到最后部分,因为“张”的拼音是“zhang”。也就是说,字典的正文部分本身就是一个目录,您不需要再去查其他目录来找到您需要找的内容。我们把这种正文内容本身就是一种按照一定规则排列的目录称为“聚集索引”。

如果您认识某个字,您可以快速地从自动中查到这个字。但您也可能会遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而需要去根据“偏旁部首”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“张”字,我们可以看到在查部首之后的检字表中“张”的页码是672页,检字表中“张”的上面是“驰”字,但页码却是63页,“张”的下面是“弩”字,页面是390页。很显然,这些字并不是真正的分别位于“张”字的上下方,现在您看到的连续的“驰、张、弩”三字实际上就是他们在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我们可以通过这种方式来找到您所需要的字,但它需要两个过程,先找到目录中的结果,然后再翻到您所需要的页码。我们把这种目录纯粹是目录,正文纯粹是正文的排序方式称为“非聚集索引”。

不使用Oracle text功能,也有很多方法可以在Oracle数据库中搜索文本可以使用标准的INSTR函数和LIKE *** 作符实现。

SELECT FROM mytext WHERE INSTR (thetext, 'Oracle') > 0;

SELECT FROM mytext WHERE thetext LIKE '%Oracle%';

有很多时候,使用instr和like是很理想的, 特别是搜索仅跨越很小的表的时候然而通过这些文本定位的方法将导致全表扫描,对资源来说消耗比较昂贵,而且实现的搜索功能也非常有限,因此对海量的文本数据进行搜索时,建议使用oralce提供的全文检索功能 建立全文检索的步骤步骤一 检查和设置数据库角色首先检查数据库中是否有CTXSYS用户和CTXAPP脚色。如果没有这个用户和角色,意味着你的数据库创建时未安装intermedia功能。你必须修改数据库以安装这项功能。 默认安装情况下,ctxsys用户是被锁定的,因此要先启用ctxsys的用户。 步骤二 赋权 在ctxsys用户下把ctx_ddl的执行权限赋于要使用全文索引的用户,例:

grant execute on ctx_ddl to pomoho;

步骤三 设置词法分析器(lexer)

Oracle实现全文检索,其机制其实很简单。即通过Oracle专利的词法分析器(lexer),将文章中所有的表意单元(Oracle 称为 term)找出来,记录在一组 以dr$开头的表中,同时记下该term出现的位置、次数、hash 值等信息。检索时,Oracle 从这组表中查找相应的term,并计算其出现频率,根据某个算法来计算每个文档的得分(score),即所谓的‘匹配率’。而lexer则是该机制的核心,它决定了全文检索的效率。Oracle 针对不同的语言提供了不同的 lexer, 而我们通常能用到其中的三个:

n basic_lexer: 针对英语。它能根据空格和标点来将英语单词从句子中分离,还能自动将一些出现频率过高已经失去检索意义的单词作为‘垃圾’处理,如if , is 等,具有较高的处理效率。但该lexer应用于汉语则有很多问题,由于它只认空格和标点,而汉语的一句话中通常不会有空格,因此,它会把整句话作为一个 term,事实上失去检索能力。以‘中国人民站起来了’这句话为例,basic_lexer 分析的结果只有一个term ,就是‘中国人民站起来了’。此时若检索‘中国’,将检索不到内容。

n chinese_vgram_lexer: 专门的汉语分析器,支持所有汉字字符集(ZHS16CGB231280 ZHS16GBK ZHT32EUC ZHT16BIG5 ZHT32TRIS ZHT16MSWIN950 ZHT16HKSCS UTF8 )。该分析器按字为单元来分析汉语句子。‘中国人民站起来了’这句话,会被它分析成如下几个term: ‘中’,‘中国’,‘国人’,‘人民’,‘民站’,‘站起’,起来’,‘来了’,‘了’。可以看出,这种分析方法,实现算法很简单,并且能实现‘一网打尽’,但效率则是差强人意。

n chinese_lexer: 这是一个新的汉语分析器,只支持utf8字符集。上面已经看到,chinese vgram lexer这个分析器由于不认识常用的汉语词汇,因此分析的单元非常机械,像上面的‘民站’,‘站起’在汉语中根本不会单独出现,因此这种term是没有意义的,反而影响效率。chinese_lexer的最大改进就是该分析器 能认识大部分常用汉语词汇,因此能更有效率地分析句子,像以上两个愚蠢的单元将不会再出现,极大 提高了效率。但是它只支持 utf8, 如果你的数据库是zhs16gbk字符集,则只能使用笨笨的那个Chinese vgram lexer

如果不做任何设置,Oracle 缺省使用basic_lexer这个分析器。要指定使用哪一个lexer, 可以这样 *** 作:

第一. 当前用户下下建立一个preference(例:在pomoho用户下执行以下语句)

exec ctx_ddlcreate_preference ('my_lexer', 'chinese_vgram_lexer');

第二. 在建立全文索引索引时,指明所用的lexer:

CREATE INDEX myindex ON mytable(mycolumn) indextype is ctxsyscontext

parameters('lexer my_lexer');

这样建立的全文检索索引,就会使用chinese_vgram_lexer作为分析器。

步骤四 建立索引

通过以下语法建立全文索引

CREATE INDEX [schema]index on [schema]table(column) INDEXTYPE IS ctxsyscontext [ONLINE]

LOCAL [(PARTITION [partition] [PARAMETERS('paramstring')]

[, PARTITION [partition] [PARAMETERS('paramstring')]])]

[PARAMETERS(paramstring)] [PARALLEL n] [UNUSABLE];

例:

CREATE INDEX ctx_idx_menuname ON pubmenu(menuname)

indextype is ctxsyscontext parameters('lexer my_lexer')

步骤五 使用索引

使用全文索引很简单,可以通过:

select from pubmenu where contains(menuname,'上传')>0

全文索引的种类

建立的Oracle Text索引被称为域索引(domain index),包括4种索引类型:

l CONTEXT

2 CTXCAT

3 CTXRULE

4 CTXXPATH

依据你的应用程序和文本数据类型你可以任意选择一种。

对多字段建立全文索引

很多时候需要从多个文本字段中查询满足条件的记录,这时就需要建立针对多个字段的全文索引,例如需要从pmhsubjects(专题表)的 subjectname(专题名称)和briefintro(简介)上进行全文检索,则需要按以下步骤进行 *** 作:

Ø 建议多字段索引的preference

以ctxsys登录,并执行:

EXEC ctx_ddlcreate_preference(' ctx_idx_subject_pref',

'MULTI_COLUMN_DATASTORE');

Ø 建立preference对应的字段值(以ctxsys登录)

EXEC ctx_ddlset_attribute(' ctx_idx_subject_pref ','columns','subjectname,briefintro');

Ø 建立全文索引

CREATE INDEX ctx_idx_subject ON pmhsubjects(subjectname)

INDEXTYPE ISctxsysCONTEXT PARAMETERS('DATASTORE ctxsysctx_idx_subject_pref lexer my_lexer')

Ø 使用索引

select from pmhsubjects where contains(subjectname,'李宇春')>0

全文索引的维护

对于CTXSYSCONTEXT索引,当应用程序对基表进行DML *** 作后,对基表的索引维护是必须的。索引维护包括索引同步和索引优化。

在索引建好后,我们可以在该用户下查到Oracle自动产生了以下几个表:(假设索引名为myindex):

DR$myindex$I、DR$myindex$K、DR$myindex$R、DR$myindex$N其中以I表最重要,可以查询一下该表,看看有什么内容:

SELECT token_text, token_count FROM dr$i_rsk1$I WHERE ROWNUM <= 20;

这里就不列出查询接过了。可以看到,该表中保存的其实就是Oracle 分析你的文档后,生成的term记录在这里,包括term出现的位置、次数、hash值等。当文档的内容改变后,可以想见这个I表的内容也应该相应改变,才能保证Oracle在做全文检索时正确检索到内容(因为所谓全文检索,其实核心就是查询这个表)。这就用到sync(同步) 和 optimize(优化)了。

同步(sync): 将新的term 保存到I表;

优化(optimize): 清除I表的垃圾,主要是将已经被删除的term从I表删除。

当基表中的被索引文档发生insert、update、delete *** 作的时候,基表的改变并不能马上影响到索引上直到同步索引。可以查询视图 CTX_USER_PENDING查看相应的改动。例如:

SELECT pnd_index_name, pnd_rowid,

TO_CHAR (pnd_timestamp, 'dd-mon-yyyy hh24:mi:ss') timestamp

FROM ctx_user_pending;

该语句的输出类似如下:

PND_INDEX_NAME PND_ROWID TIMESTAMP

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

MYINDEX AAADXnAABAAAS3SAAC 06-oct-1999 15:56:50

同步和优化方法: 可以使用Oracle提供的ctx_ddl包同步和优化索引

一 对于CTXCAT类型的索引来说, 当对基表进行DML *** 作的时候,Oracle自动维护索引。对文档的改变马上反映到索引中。CTXCAT是事务形的索引。

索引的同步

在对基表插入,修改,删除之后同步索引。推荐使用sync同步索引。语法:

ctx_ddlsync_index(

idx_name IN VARCHAR2 DEFAULT NULL

memory IN VARCHAR2 DEFAULT NULL,

part_name IN VARCHAR2 DEFAULT NULL

parallel_degree IN NUMBER DEFAULT 1);

idx_name 索引名称

memory 指定同步索引需要的内存。默认是系统参数DEFAULT_INDEX_MEMORY 。

指定一个大的内存时候可以加快索引效率和查询速度,且索引有较少的碎片

part_name 同步哪个分区索引。

parallel_degree 并行同步索引。设置并行度。

例如:

同步索引myindex:Exec ctx_ddlsync_index ('myindex');

实施建议:建议通过oracle的job对索引进行同步

索引的优化

经常的索引同步将会导致你的CONTEXT索引产生碎片。索引碎片严重的影响了查询的反应速度。你可以定期优化索引来减少碎片,减少索引大小,提高查询效率。

当文本从表中删除的时候,Oracle Text标记删除的文档,但是并不马上修改索引。因此,就的文档信息占据了不必要的空间,导致了查询额外的开销。你必须以FULL模式优化索引,从索引中删除无效的旧的信息。这个过程叫做垃圾处理。当你经常的对表文本数据进行更新,删除 *** 作的时候,垃圾处理是很必要的。

exec ctx_ddloptimize_index ('myidx', 'full');

实施建议:每天在系统空闲的时候对全文索引进行相应的优化,以提高检索的效率

PS定时优化索引

3定时优化同步域索引

创建定时任务,定期优化和同步域索引

SQL> create or replace procedure hsp_sync_index as

2 begin

3 ctx_ddlsync_index('id_cont_msg');

4 end;

5 /

Procedure created

Elapsed: 00:00:0008

SQL> VARIABLE jobno number;

SQL> BEGIN

2 DBMS_JOBSUBMIT(:jobno,'hsp_sync_index();',

3 SYSDATE, 'SYSDATE + (1/24/4)');

4 commit;

5 END;

6 /

PL/SQL procedure successfully completed

Elapsed: 00:00:0027

SQL> create or replace procedure hsp_optimize_index as

2 begin

3 ctx_ddloptimize_index('id_cont_msg','FULL');

4 end;

5 /

SQL> VARIABLE jobno number;

SQL> BEGIN

2 DBMS_JOBSUBMIT(:jobno,'hsp_optimize_index();',

3 SYSDATE, 'SYSDATE + 1');

4 commit;

5 END;

6 /

Procedure created

Elapsed: 00:00:0003

PL/SQL procedure successfully completed

Elapsed: 00:00:0002

SQL>

应该建索引的字段:1经常作为查询条件的字段2外键3经常需要排序的字段4分组排序的字段

应该少建或者不建索引的字段有:1表记录太少,2经常需要插入,删除,修改的表,3表中数据重复且分布平均的字段

一些SQL的写法会限制索引的使用:1where子句中如果使用in、or、like、!=,均会导致索引不能正常使用,将""换成">and=chr(0)";2使用函数时,该列就不能使用索引。3比较不匹配数据类型时,该索引将会被忽略。

一些SQL语句优化的写法:1如果from是双表的查询时,大表放在前面,小表放在后面(基础表)。最后面的表是基础表。(只在基于规则的优化器中有效)2如果三表查询时,选择交叉表(table)作为基础表(只在基于规则的优化器中有效)3写where条件时,有索引字段的判断在前,其它字段的判断在后;如果where条件中用到复合索引,按照索引列在复合索引中出现的顺序来依次写where条件;4查询数量较大时,使用表连接代替IN,EXISTS,NOTIN,NOTEXISTS等。5ORACLE采用自下而上的顺序解析WHERE子句,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾

索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。

一个索引是存储的表中一个特定列的值数据结构(最常见的是B-Tree,还有哈希表索引和R-tree)。索引是在表的列上创建。所以,要记住的关键点是索引包含一个表中列的值,并且这些值存储在一个数据结构中。请记住记住这一点:索引是一种数据结构 

使用索引的全部意义就是通过缩小一张表中需要查询的记录(行)的数目来加快搜索的速度

假设有一张学生名单表,有一百条数据。要查询其中名字为 小明 的学生。

一般采取select from students where name ='小明';由于我们想要得到每一个名字为小明的学生信息,在查询到第一个符合条件的行后,不能停止查询,因为可能还有其他符合条件的行。所以,必须一行一行的查找直到最后一行-这就意味数据库不得不检查上千行数据才能找到所以名字为小明 的学生。这就是所谓的全表扫描。

假设我们在 name这一列上创建一个B-Tree索引。当我们用SQL查找名字是‘小明 ’的学生时,不需要再扫描全表。而是用索引查找去查找名字为‘小明 ’的学生,因为索引已经按照按字母顺序排序。索引已经排序意味着查询一个名字会快很多,因为名字首字母为‘小’的学生都是排列在一起的。另外重要的一点是,索引同时存储了表中相应行的指针以获取其他列的数据。

以上就是关于数据库索引有哪几种,怎样建立索引全部的内容,包括:数据库索引有哪几种,怎样建立索引、mysql数据库,索引是怎么使用的、数据库索引的实现原理等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/10166444.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存