问题
Please see the DDL below:
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')
The users want to be able to search for VRMs like this:
select * from #VRMs where VRM LIKE '%VRM1'
The problem is that there are 100,000,000 rows in this table and the queries are taking far too long. I have come across this question: https://stackoverflow.com/questions/33210269/like-statement-taking-too-long
Unfortunately I am using an Oracle DBMS. I have imported all the VRMs into an SQL database using SSIS and have tried the following query:
select * from #VRMs where reverse(VRM) LIKE reverse('%VRM1')
The query runs in a fraction of a second. However, it runs in 487 seconds on the Oracle database. How can I optimise it to run faster in the Oracle database?
回答1:
Use function based index
create index tst_rev on tst(reverse(txt));
The query
select * from tst where reverse(txt) like 'x10%';
101x
201x
301x
401x
leads to index range scan
---------------------------------------------------------------------------------------
| 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%')
回答2:
your query takes seconds in MSSQL bcz you imported everything into temp table #VRM
in oracle you created #VRM table, the table is not temp table like it was in MSSQL, and then your imported millions of records there I think you need create index for the column VRM in the table #VRM
回答3:
Doing a quick search .. I found this link on AskTom ..
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:37336026927381
I think the solution posted by a user part way down could be useful .. To avoid any future broken links, I re-post the original in it's original form .. (with just some minor formatting editting ... ):
Why not use a builtin functionality?
March 27, 2005 - 3:40 am UTC
Reviewer: Ofir Manor from Israel
Hi Tom,
I wonder why you hand-code a functionality that is already supplied? If you want to make '%xxx%' queries faster, all you need to do is ask the text index to prepare for it, by indexing all the substrings as well. There is no need to manually write a procedural code to implement this feature... Did I miss anything?
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');
..Then this query will do:
select * from t where contains( col1,'%750776%')>0
There are some more details and preference attributes to play with here, plus an example:
http://download-west.oracle.com/docs/cd/B14117_01/text.101/b10730/cdatadic.htm#sthref750
How about that?
来源:https://stackoverflow.com/questions/33302679/like-statement-taking-too-long