Thread: planning issue

planning issue

From
Jonathan Vanasco
Date:
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

Re: planning issue

From
"Joshua D. Drake"
Date:
>
>         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/


Re: planning issue

From
Jeff Davis
Date:
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


Re: planning issue

From
Jonathan Vanasco
Date:
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
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -



Re: planning issue

From
Alban Hertroys
Date:
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 //

Re: planning issue

From
"John D. Burger"
Date:
>> 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