Optimized Query with LIKE Operator (merged) [message #379685] |
Wed, 07 January 2009 11:38 |
shankhan
Messages: 28 Registered: September 2008 Location: Pakistan
|
Junior Member |
|
|
Dear Guys,
I have a table which contains thousands (apx 15k) of country codes like:
Country_Code Country Name
93 Afghanistan (LL)
937 Afghanistan (Mobile)
9370 Afghanistan (Mobile)
....
....
Now I have written a function to which I pass a phone number and it tells me the exact corresponding country code. The SQL statement that achieves this is given below:
SELECT code_country
FROM (SELECT country_code
FROM country_codes
WHERE phone_num LIKE country_code || '%'
ORDER BY LENGTH(country_code) DESC)
WHERE ROWNUM = 1
Since I am using the LIKE operator it always performs a FULL TABLE scan. Now I have to call this function on thousands of records for which it takes lots of time.
Is there any other best way to get the country code information from the table or we can optimze the above query.
I would really appriciate your help in this regard.
|
|
|
|
Re: Optimized Query with LIKE Operator (merged) [message #379694 is a reply to message #379690] |
Wed, 07 January 2009 12:40 |
andrew again
Messages: 2577 Registered: March 2000
|
Senior Member |
|
|
Oracle can (not will) use an index if you only wildcard the end of your search string.
create table country_codes (country_code varchar2(10));
create index country_codes_ix1 on country_codes (country_code);
insert into country_codes (select to_char(object_id) from dba_objects);
commit
exec dbms_stats.gather_table_stats( user, 'COUNTRY_CODES');
--FTS
SELECT country_code
FROM country_codes
WHERE country_code LIKE '%20774%'
Plan
SELECT STATEMENT ALL_ROWS Cost: 23 Bytes: 11,385 Cardinality: 2,277
1 TABLE ACCESS FULL TABLE SCOTT.COUNTRY_CODES Cost: 23 Bytes: 11,385 Cardinality: 2,277
-- index scan
SELECT country_code
FROM country_codes
WHERE country_code LIKE '20774%'
Plan
SELECT STATEMENT ALL_ROWS Cost: 2 Bytes: 5 Cardinality: 1
1 INDEX RANGE SCAN INDEX SCOTT.COUNTRY_CODES_IX1 Cost: 2 Bytes: 5 Cardinality: 1
|
|
|
|
|
Re: Optimized Query with LIKE Operator (merged) [message #379711 is a reply to message #379685] |
Wed, 07 January 2009 13:39 |
shankhan
Messages: 28 Registered: September 2008 Location: Pakistan
|
Junior Member |
|
|
The Output I have already mentioned at the start of my question: i.e; I will be giving a phone number and the output will be a country code.
On average this query returns about 4 rows out of 10K Unique Country Codes table.
Like if I have country codes as given below:
91
912
913
914
915
....
And I write a query as given below:
SELECT country_code
FROM (SELECT country_code
FROM country_codes
WHERE '9123434345' LIKE country_code || '%'
ORDER BY LENGTH(country_code) DESC)
WHERE ROWNUM = 1
Then this query will be fetching two rows out of which I will get only one row with greater country code length as per my business logic.
[Updated on: Wed, 07 January 2009 13:50] Report message to a moderator
|
|
|
|
Re: Optimized Query with LIKE Operator (merged) [message #379752 is a reply to message #379728] |
Wed, 07 January 2009 19:47 |
rleishman
Messages: 3728 Registered: October 2005 Location: Melbourne, Australia
|
Senior Member |
|
|
Nice solution to a tricky problem, Barbara.
Can you move the CONNECT BY inline view so that it becomes an IN sub-query? That would make the syntax a bit more intuitive. Something like:
SELECT country_code
FROM (
SELECT country_code
FROM country_codes
WHERE country_code IN (
SELECT SUBSTR (:searchstring, 1, LEVEL) codestring
FROM DUAL
CONNECT BY LEVEL <= LENGTH (:searchstring)
)
ORDER BY length(country_code) DESC
)
WHERE ROWNUM = 1
/
Ross Leishman
|
|
|
|