Re: Function in WHERE performance issue

From: Rich Jesse <rjoralist_at_society.servebeer.com>
Date: Mon, 13 Jul 2009 09:25:19 -0500 (CDT)
Message-ID: <cc825c28b26ac6580b4408f5e8c0f8bc.squirrel_at_society.servebeer.com>



Hey Stephane,

>> select /*+ first_rows(1) */ aa.*
>> from geo_location aa,
>> geo_blocks b
>> where aa.locid = b.locid
>> and ip2number('192.168.1.1') between b.startipnum and b.endipnum;
>>
> Rich,
>
> It's a question of bounds.
>
> Just add the additional condition
>
> and b.startipnum >= to_number(substr('&ip_addr', 1,
> instr('&ip_addr'), '.') - 1)) * 16777216
>
> and you should feel the difference. No need to create a FBI on
> ip2number().

But I haven't created an FBI. And while the addition of the above to the WHERE clause does cause a sub-second return, reworking the statement to:

select /* first_rows(1) */ aa.*
from geo_location aa,

        geo_blocks b
where aa.locid = b.locid
-- and ip2number(:p_ipaddr) between b.startipnum and b.endipnum and to_number(substr(:p_ipaddr, 1,instr(:p_ipaddr, '.') - 1)) * 16777216 between b.startipnum and b.endipnum

...does not. While somewhat faster at ~5s, it's not sub-second.

> And, please, remove the hint, it's ugly.

I'd love to. I only have one hint on one query on this system and it's for an outline. However, without the hint I get an FTS, which I know isn't necessary, based on the sub-second response times I can get by changing the predicate. Removing it would certainly be ideal.

I'll probably be running this statement in PL, where I can parse the IP via the function and then pass the result to the SQL via bind, so my question is more academic. But I'm having a mental issue of generalizing the situation so that I can apply it to other future issues like this.

Thanks for the ideas!

Rich

--
http://www.freelists.org/webpage/oracle-l
Received on Mon Jul 13 2009 - 09:25:19 CDT

Original text of this message