首页 > 数据库 >文本列的性能优化?深入Oracle全文索引

文本列的性能优化?深入Oracle全文索引

时间:2024-10-29 18:49:33浏览次数:8  
标签:索引 全文索引 test TEST Oracle 文本 select desc

一.什么是全文索引?

全文索引通过分析和处理文本,将文档中的单词分解为词条(tokens),然后存储词条与其所在文档的映射关系。这使得数据库可以快速定位包含特定关键字的记录,而不必对所有文本逐字匹配。

二.实验

CREATE TABLE test (
    TEST_ID   NUMBER(6),
    TEST_NAME VARCHAR2(50),
    TEST_DESC VARCHAR2(4000)
);
BEGIN
    FOR i IN 1..10000 LOOP
        INSERT INTO test (TEST_ID,TEST_NAME,TEST_DESC) 
        VALUES (
            i, 
            'Product ' || i, 
            DBMS_RANDOM.STRING('A', 2000)
        );
    END LOOP;
    COMMIT;
END;
/

 创建一个普通索引

create index idx_test on test(test_desc);

查看执行计划,检查索引是否生效

 select * from test where test_desc like 'LRbwu%';

061a05344b9145c3aed953780b82ae2d.png

 到此,是没有任何问题的,在这种情况中,我们知道test_id 是以什么字符开头的


 

那么就会有这么一种情况,我们不知道这个内容开头是什么,只知道中间是什么,有什么关键字,那么这种情况 我们就需要<%内容%>,那么这种情况还会走索引吗?

select * from test where test_desc like '%AoaUR%';

ac80bd1246904582b226ddb63d6c4d1d.png

 这时候我们发现,走了全表扫描,所以普通的索引解决不了我们只知道关键字,而不知道以什么字符开头的情况。

这也可以理解,B Tree索引只顺序存储了表中列值以及对应的rowid,并且对于索引中字符串的排序,是根据该字符串第一个字符的ASCⅡ码,第一个字符的ASCⅡ码相同,再解析第二个。在这种情况中,我们不知道字符串前面的字符是什么,所以B Tree索引无法使用。

所以这种场景就需要我们今天介绍的内容-全文索引


三.使用全文索引

 

在使用之前,数据库中必须要系统用户CTXSYS,如果没有则有两种方式来配置

1.dbca配置数据库,这里不做演示,配置后产生了CTXSYS用户

35e5cef47d7d4cee81e0a23778356236.png

2.跑脚本

/u01/app/oracle/product/19.3.0/dbhome_1/ctx/admin
ls -al catctx.sql

在数据库中跑这个脚本就好。

 

创建全文索引

确认已存在的段

col segment_name for a30
col object_name for a30
select segment_name ,segment_type from user_segments;

18c8fe4c4b9f4758b598d29d9a136c59.png

create index idx_ctx_test on test(test_desc) indextype is ctxsys.context;

79f29b61496343dabbe29b90861f54a3.png

这里我们发现,全文索引可以建立在普通索引之上,意思是表中的一列有索引了,仍然可以建立全文索引,说明全文索引的结构和普通索引的结构肯定是有区别的。

select * from test where contains(test_desc,'LRbwu') > 0;

5840c208c7944980b1ff628c353754c0.png

 可以看到sql语句走了全文索引。

再查看一下现在的段都有哪些

col segment_name for a30
col object_name for a30
select segment_name ,segment_type from user_segments;

ce955e6cdc84465ebae3d7bab9d4aa77.png

可以看到段多了很多TEST是基本表,剩下的除了IDX_TEST是普通索引,剩下的全是全文索引,

但是我们刚才创建的索引名字是idx_ctx_test,发现找不到,这是因为全文索引只是逻辑上的概念,他没有存储对象,它的实现都依赖这些表。

 

四.深入全文索引

我们来看看这几张表

1e07b6d7c46544c7806c959be3d0de39.png

出现的token给他编一个号,并且存储了重复出现的次数(TOKEN_COUNT)

我们随机搜索一个字符串。

2319e2aea0084f00b5d547bdcbbd2064.png

DR$IDX_CTX_TEST$I 这个表把test_desc 这一列的值像字典一样保存出来,编一个号,并且总结出现的次数。但由于我是使用的DBMS_RANDOM.STRING 这个包随机创建的数据,所以这个表非常的大。

编了号之后,仍然不知道这些词在哪个地方,这时候就需要另外一张表 DR$IDX_CTX_TEST$K

 061f0c48b5ac49fd8f61057c3842dca2.png

 55ccc6164b164605961a78c0b5a377ac.png

这个TEXTKEY就是rowid了,我们可以根据TESTKEY找到数据了.

也就是说 DR$IDX_CTX_TEST$I  会生成token和编号,DR$IDX_CTX_TEST$K 表示对应的这些编号数据存放在哪里

349b900f0b8d4d32a0988cba26cb3a0f.png

 

五.全文索引的维护

在TEST表上做DML操作,看索引与表是否同步4

1.insert

select * from test where test_desc like 'nihao';

c17d31deb2dd4b3eacd19f38a266ff65.png

insert into test values (999,'DBA','nihao');

 57a8bb0f56494de481e3410bec2a41fe.png

此时通过全文索引查找数据,查看是否更新  

select * from test where contains(test_desc,'nihao') > 0;

61ecbbb87f594490bd3f358f1ae1d998.png

发现全文索引没有更新,这就说明表中的数据变了,而全文索引中的数据没有变。

使用sys查看ctxsys.dR$pending表

select * from ctxsys.dR$pending;

3e55b96f11ac4a4286fd341e417546c1.png

 这个表里面的数据就是我刚才插入的数据,只是没有更新到全文索引

这种情况需要重建全文索引。

alter index idx_ctx_test rebuild;

再次使用全文索引查询发现更新了

56038c07225c41388b76df26546a237a.png

 

2.delete

941e56c3006a4c9d8913960d25a5387b.png

 查看全文索引

f626768693ec4680b29b0cef28065f48.png

 这里可以发现,delete与insert语句不同,delete后 全文索引也更新了。

3.update,可以自己做实验,update也是不同步全文索引的。

 

六.全文索引创建同步的方式

一遇到插入的场景就需要重建全文索引,这也太麻烦了,所以,我们可以在创建全局索引的时候指定同步的方式。

提交时同步

create index idx_ctx_test on test(test_desc) indextype is ctxsys.context parameters('sync (on commit)');

 指定时间同步(建议)

需要给用户 job的权限

grant create job to user1;

 8ae23f100a2344e788b757590364bf8e.png

 例如:每天晚上两点来同步全文索引

create index idx_ctx_test on test(test_desc) indextype is ctxsys.context parameters ('sync (every "trunc(sysdate) + 2/24")');

20d45be2dddd40afa57e2bbeaf2fd8cd.png

 

 

 

 

 

标签:索引,全文索引,test,TEST,Oracle,文本,select,desc
From: https://blog.csdn.net/dnuiking/article/details/143161919

相关文章

  • ORACLE自定义函数
    CREATE[ORREPLACE]FUNCTION函数名称(arg1[{IN|OUT|INOUT}]TYPE1[DEFAULTVALUE1], [arg2[{IN|OUT|INOUT}]TYPE2[DEFAULTVALUE1]],……[argn[{IN|OUT|INOUT}]TYPE[DEFAULTVALUE]])[AUTHIDDEFINER|CURRENT_USER]RETURNreturn_typeIS|A......
  • ORACLE存储过程
    CREATE[ORREPLACE]PROCEDUREprocedure_name([arg1[IN|OUT|INOUT]]type1[DEFAULTvalue1],[arg2[IN|OUT|INOUT]]type2[DEFAULTvalue1]],......[arg[IN|OUT|INOUT]]type[DEFAULTvalue])[AUTHIDDEFINER|CURRENT_USER]IS|AS&......
  • 强大的文本编辑器Notepad++8.4.6 最新版
          Notepad++最新版是一款多功能的代码编辑工具。Notepad++官方版支持27种编程语言,涵盖C、C++、Java、C#,、XML、HTML,、PHP、python等等,能够帮助程序员提高编辑效率。Notepad++软件支持python与sql代码高亮功能,并且免费开源,能够完美地取代微软视窗的记事本功......
  • oracle如何查询表是否被锁
    oracle查询表是否被锁的步骤:1.登录到数据库;2.检查DBA_LOCK视图;3.检查V$LOCKED_OBJECT视图;4.使用DBMS_LOCK包。首先,使用SQL*Plus、SQLDeveloper或其他Oracle数据库客户端,以具有足够权限的数据库用户身份登录到Oracle数据库。1.登录到数据库首先,使用SQL*Plus、SQLDeveloper或......
  • 安装Oracle 23ai报错,求大佬指点
    {IDS_OracleConfigDlg_DatabaseConfigFailedMsg}Anerroroccurred whileconfiguringOracleFreedatabase.CheckthelogsatG:\Oracle_23ai\cfgtoollogs\dbcaandtryagain.【G:\Oracle_23ai\cfgtoollogs\dbca】log文件 正在对命令行参数进行语法分析:参数......
  • python从QQ邮箱中读取最新邮件,并以纯文本的方式在控制台显示
    importimaplibimportemailfromemail.policyimportdefaultfromhtml2textimporthtml2textIMAP_SERVER='imap.qq.com'#例如:'imap.gmail.com'IMAP_PORT=993#默认IMAP端口为993EMAIL_ADDRESS='[email protected]'#你的邮箱地址......
  • 一个包含了超过 200 个实用脚本的 Python 脚本库,如文件管理、网络操作、图像处理、文
    前言在日常的工作和生活中,我们经常会遇到一些重复性的任务,如文件管理、网络cao作、图像处理、文本处理等。这些任务虽然简单,但如果频繁手动cao作,不仅耗时耗力,还容易出错。现有的软件虽然能处理一部分问题,但往往功能单一,无法满足多样化的需求。那么,有没有一款软件能够处理这种......
  • python实战(三)——文本向量化/文本表示
    一、概念    文本向量化是自然语言处理领域的重要环节,也是现在大语言模型开发重要基础。计算机程序无法理解文字信息(实际上非数值类型的信息都无法理解),因此我们需要将文字信息转换成计算机程序可理解的数值类型。通俗来说就是我们的算法模型是一系列函数和公式的组合......
  • 鸿蒙开发融云demo发送文本消息
    鸿蒙开发融云demo发送文本消息融云鸿蒙版是不带UI的,得自己一步步搭建。这次说如何发送文本消息,并且显示文本消息一、思路发送用:IMEngine.getInstance().sendMessage显示文本:Text(ImUtils.dealMyTextContent(this.msg.contentasTextMessage)).l......
  • Oracle 第4章:SQL基础
    在学习Oracle数据库的第四章——SQL基础时,我们会涉及到SQL(StructuredQueryLanguage)的基本概念以及如何使用基本的SQL查询语句来获取数据。以下是这一章节中可能涵盖的一些关键点:SQL简介SQL是一种用于管理和处理数据库的标准计算机语言。它主要用于存储、检索、管理和操......