planning issue

Started by Jonathan Vanascoabout 19 years ago6 messagesgeneral
Jump to latest
#1Jonathan Vanasco
postgres@2xlp.com

if you have time, could you offer advice on this:

i'm doing a database cleanup right now -- 1.4M records -- and each
query is taking 1 second

i can't really wait 2 weeks for this to finish , so I'm hoping that
someone will be able to help out

the issue is that the planner keeps doing a sequential scan, despite
the fact that the requesite columns are indexed.

hoping someone may be able to offer advice:.

SELECT
*
FROM
table_a
WHERE
id != 10001
AND
(
( field_1 ilike '123' )
OR
( field_2 ilike 'abc' )
)

QUERY PLAN
------------------------------------------------------------------------
------------------------------------------------------------------------
-------------------------
Seq Scan on table_a (cost=0.00..22779.68 rows=1 width=346)
Filter: ((id <> 10001) AND (((field_1)::text ~~* '123'::text) OR
((field_2)::text ~~* 'abc'::text)))

however, i have the following indexes:

"table_a__pkey" PRIMARY KEY, btree (id)
"table_a__idx__field_1" btree (field_1)
"table_a__idx__field_2" btree (field_2)

can anyone offer advice to help me use the indexes on this ?

// Jonathan Vanasco

#2Joshua D. Drake
jd@commandprompt.com
In reply to: Jonathan Vanasco (#1)
Re: planning issue

QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Seq Scan on table_a (cost=0.00..22779.68 rows=1 width=346)
Filter: ((id <> 10001) AND (((field_1)::text ~~* '123'::text) OR
((field_2)::text ~~* 'abc'::text)))

however, i have the following indexes:

"table_a__pkey" PRIMARY KEY, btree (id)
"table_a__idx__field_1" btree (field_1)
"table_a__idx__field_2" btree (field_2)

can anyone offer advice to help me use the indexes on this ?

create a function lower index and instead of calling ilike call ~
lower('123')

Joshua D. Drake

// Jonathan Vanasco

---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster

--

=== The PostgreSQL Company: Command Prompt, Inc. ===
Sales/Support: +1.503.667.4564 || 24x7/Emergency: +1.800.492.2240
Providing the most comprehensive PostgreSQL solutions since 1997
http://www.commandprompt.com/

Donate to the PostgreSQL Project: http://www.postgresql.org/about/donate
PostgreSQL Replication: http://www.commandprompt.com/products/

#3Jeff Davis
pgsql@j-davis.com
In reply to: Joshua D. Drake (#2)
Re: planning issue

On Fri, 2007-03-16 at 12:17 -0700, Joshua D. Drake wrote:

QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Seq Scan on table_a (cost=0.00..22779.68 rows=1 width=346)
Filter: ((id <> 10001) AND (((field_1)::text ~~* '123'::text) OR
((field_2)::text ~~* 'abc'::text)))

however, i have the following indexes:

"table_a__pkey" PRIMARY KEY, btree (id)
"table_a__idx__field_1" btree (field_1)
"table_a__idx__field_2" btree (field_2)

can anyone offer advice to help me use the indexes on this ?

create a function lower index and instead of calling ilike call ~
lower('123')

To clarify a little:

CREATE INDEX table_a_lower_field_1_idx on table_a ((lower(field_1)));
CREATE INDEX table_a_lower_field_2_idx on table_a ((lower(field_2)));
SELECT
*
FROM
table_a
WHERE
id != 10001
AND
(
( lower(field_1) = '123' )
OR
( lower(field_2) = 'abc' )
)

That should be able to use your indexes correctly.

Regards,
Jeff Davis

#4Jonathan Vanasco
postgres@2xlp.com
In reply to: Jeff Davis (#3)
Re: planning issue

On Mar 16, 2007, at 3:48 PM, Jeff Davis wrote:

To clarify a little:

No clarifcation needed. Joshua Drake's suggestion made perfect sense
and I was able to implement in 2 seconds.

works like a charm!

ETA 2 weeks -> 30mins

Thanks to all.

// Jonathan Vanasco

| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
| SyndiClick.com
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
| FindMeOn.com - The cure for Multiple Web Personality Disorder
| Web Identity Management and 3D Social Networking
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
| RoadSound.com - Tools For Bands, Stuff For Fans
| Collaborative Online Management And Syndication Tools
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -

#5Alban Hertroys
alban@magproductions.nl
In reply to: Jonathan Vanasco (#1)
Re: planning issue

Jonathan Vanasco wrote:

hoping someone may be able to offer advice:.

SELECT
*
FROM
table_a
WHERE
id != 10001
AND
(
( field_1 ilike '123' )
OR
( field_2 ilike 'abc' )
)

You seem to use that ilike expression merely as a case-insensitive
equals. May as well use that in combination with indices on
lower(field_[12]). It's probably faster than like or a regex match.

--
Alban Hertroys
alban@magproductions.nl

magproductions b.v.

T: ++31(0)534346874
F: ++31(0)534346876
M:
I: www.magproductions.nl
A: Postbus 416
7500 AK Enschede

// Integrate Your World //

#6John D. Burger
john@mitre.org
In reply to: Jeff Davis (#3)
Re: planning issue

create a function lower index and instead of calling ilike call ~
lower('123')

To clarify a little:

CREATE INDEX table_a_lower_field_1_idx on table_a ((lower(field_1)));
CREATE INDEX table_a_lower_field_2_idx on table_a ((lower(field_2)));
SELECT
*
FROM
table_a
WHERE
id != 10001
AND
(
( lower(field_1) = '123' )
OR
( lower(field_2) = 'abc' )
)

To put my own two cents in, I always try to make sure I use lower()
in the query on everything I'm comparing, as Josh originally
suggested, so I would do this:

lower(field_2) = lower('abc')

This ensures that both sides of the comparison are being downcased
the same way - otherwise there might be a discrepancy due to
collation differences, etc., between the client and the server sides.

This seems silly in this example, but I think it's a good habit.

- John Burger
MITRE