Re: [HACKERS] Help/advice/suggestions on query optimizer for a large table

Поиск
Список
Период
Сортировка
От Bruce Momjian
Тема Re: [HACKERS] Help/advice/suggestions on query optimizer for a large table
Дата
Msg-id 199905101640.MAA07611@candle.pha.pa.us
обсуждение исходный текст
Ответ на Re: [HACKERS] Help/advice/suggestions on query optimizer for a large table  (Thomas Lockhart <lockhart@alumni.caltech.edu>)
Список pgsql-hackers
OK, so here is the answer to this question.  Thanks Thomas.



> > Anyway, if I submit a query such as:
> >         select * from mytable where x=3.14 and y=6.28;
> > it takes about 3 minutes to return the record.  Both x and y are indexed:
> > And "explain" on the select query above says it's doing a sequential scan.
> > However if I say:
> >         select * from mytable where x='3.14'::float4 and y='6.28'::float4;
> > it takes about 3 seconds!  And now "explain" says it's doing an indexed
> > scan.
> > My understanding is that the query optimizer should pick the index
> > scan for this query based on the cost.
> 
> This is a known feature. The Postgres parser converts an unquoted 3.14
> to a float8, which is not the same as the float4 column you have
> indexed. And the optimizer is not (yet) bright enough to convert
> constants to the column type, and then use the available indexes.
> 
> In fact, the apparently more desirable strategy is not particularly
> easy to get right. Look at this example:
> 
>   create table t1 (i int4);
>   (insert a bunch of data)
>   create index tx on t1 using btree(i);
>   vacuum;
>   select * from t1 where i < 3.5;
> 
> In this case, we can't convert the 3.5 to an integer (3) without
> changing the comparison operator to "<=". And in your case,
> "downconverting" the float8 to a float4 probably would risk the same
> problem. So Postgres *promotes* the float4s to float8s, and has to do
> a sequential scan along the way.
> 
> Anyway, afaik you have two options. The first is to surround the
> "3.14" in your example with single quotes (probably the coersion to
> float4 is unnecessary). The second is to create a function index on
> your table, to allow your queries to use float8 arguments
> transparently:
> 
>   create index mx on mytable using btree (float8(x));
>   create index my on mytable using btree (float8(y));
> 
> If you are hiding all of the queries inside an app, then I'd suggest
> the first technique. If you are going to be doing a lot of direct SQL,
> then you might want to use the second.
> 
>                            - Tom
> 
> -- 
> Thomas Lockhart                lockhart@alumni.caltech.edu
> South Pasadena, California
> 
> 


--  Bruce Momjian                        |  http://www.op.net/~candle maillist@candle.pha.pa.us            |  (610)
853-3000+  If your life is a hard drive,     |  830 Blythe Avenue +  Christ can be your backup.        |  Drexel Hill,
Pennsylvania19026
 


В списке pgsql-hackers по дате отправления:

Предыдущее
От: Vadim Mikheev
Дата:
Сообщение: Re: [HACKERS] INSERT INTO ... SELECT eats all my memory
Следующее
От: jwieck@debis.com (Jan Wieck)
Дата:
Сообщение: Re: [HACKERS] create view as select distinct (fwd)