LIKE声明花了太长时间

时间:2015-10-23 12:46:31

标签: sql oracle oracle11g

请参阅下面的DDL:

create table #VRMs (ID INT, VRM VARCHAR(10))
INSERT INTO #VRMs VALUES (1,'VRM1')
INSERT INTO #VRMs VALUES (1,'VRM2')
INSERT INTO #VRMs VALUES (1,'VRM3')

用户希望能够像这样搜索VRM:

select * from #VRMs where VRM LIKE '%VRM1'

问题是此表中有100,000,000行,查询耗时太长。我遇到过这个问题:https://stackoverflow.com/questions/33210269/like-statement-taking-too-long

不幸的是我使用的是Oracle DBMS。我已使用SSIS将所有VRM导入SQL数据库,并尝试了以下查询:

select * from #VRMs where reverse(VRM) LIKE reverse('%VRM1')

查询在几分之一秒内运行。但是,它在Oracle数据库上运行487秒。如何优化它以在Oracle数据库中更快地运行?

3 个答案:

答案 0 :(得分:2)

使用function based index

 create index tst_rev on tst(reverse(txt));

查询

 select * from tst where reverse(txt) like 'x10%';

 101x
 201x
 301x
 401x

导致索引范围扫描

 ---------------------------------------------------------------------------------------
 | Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
 ---------------------------------------------------------------------------------------
 |   0 | SELECT STATEMENT            |         |   100 | 10400 |     0   (0)| 00:00:01 |
 |   1 |  TABLE ACCESS BY INDEX ROWID| TST     |   100 | 10400 |     0   (0)| 00:00:01 |
 |*  2 |   INDEX RANGE SCAN          | TST_REV |    18 |       |     0   (0)| 00:00:01 |
 ---------------------------------------------------------------------------------------

 ....

    2 - access(REVERSE("TXT") LIKE 'x10%')
   filter(REVERSE("TXT") LIKE 'x10%')

答案 1 :(得分:0)

您的查询在MSSQL中需要几秒钟bcz您将所有内容导入 temp 表#VRM

在oracle中你创建了#VRM表,该表不是像在MSSQL中那样的临时表,然后你在那里导入数百万条记录 我认为你需要在表#VRM

中为列VRM创建索引

答案 2 :(得分:0)

快速搜索..我在AskTom上找到了这个链接..

https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:37336026927381

我认为用户部分向下发布的解决方案可能很有用.. 为了避免将来出现任何损坏的链接,我会重新发布原始格式的原始内容..(仅进行一些小格式编辑...):

  

为什么不使用内置功能?

     

2005年3月27日 - UTC时间凌晨3:40

     

评论员:来自以色列的Ofir庄园

     

嗨,汤姆,

     

我想知道为什么你手工编写已经提供的功能?如果你想制作'%xxx%'查询速度更快,您需要做的就是通过索引所有子字符串来要求文本索引为它做准备。无需手动编写程序代码来实现此功能......我是否遗漏了什么?

     

begin ctx_ddl.create_preference('SUBSTRING_PREF', 'BASIC_WORDLIST'); ctx_ddl.set_attribute('SUBSTRING_PREF', 'SUBSTRING_INDEX','TRUE'); end; drop index search_idx; create index search_idx on T(col1) indextype is ctxsys.context parameters ('wordlist SUBSTRING_PREF MEMORY 50M');   ..

     

然后此查询将执行:

     

select * from t where contains( col1,'%750776%')>0

     

这里还有一些细节和偏好属性,加上一个例子:

     

http://download-west.oracle.com/docs/cd/B14117_01/text.101/b10730/cdatadic.htm#sthref750

     

怎么样?