Обсуждение: Why is it not using an index?

Поиск
Список
Период
Сортировка

Why is it not using an index?

От
Dmitry Tkach
Дата:
This must be really simple, but I just can't get it :-(
I have a table (a) with a single column (x):

           Table "a"
  Attribute |   Type   | Modifier
-----------+----------+----------
  x         | smallint |
Index: a_idx


    Index "a_idx"
  Attribute |   Type
-----------+----------
  x         | smallint
btree

The table has 10000000 rows....

Now, how come, when I do:

explain select * from a where x=3;

it says:

Seq Scan on bset  (cost=100000000.00..100175934.05 rows=303 width=2)

Why is it not using a_idx???

I even tried set enable_seqscan to off - makes no difference :-(

Any idea what is going on?

Thanks a lot!

Dima


Re: [SQL] Why is it not using an index?

От
Stephan Szabo
Дата:
On Fri, 15 Mar 2002, Dmitry Tkach wrote:

> This must be really simple, but I just can't get it :-(
> I have a table (a) with a single column (x):
>
>            Table "a"
>   Attribute |   Type   | Modifier
> -----------+----------+----------
>   x         | smallint |
> Index: a_idx
>
>
>     Index "a_idx"
>   Attribute |   Type
> -----------+----------
>   x         | smallint
> btree
>
> The table has 10000000 rows....
>
> Now, how come, when I do:
>
> explain select * from a where x=3;

You'll need to cast the 3 into smallint explicitly, either
3::smallint or CAST(3 as smallint) should work.



Re: Why is it not using an index?

От
"Gregory Wood"
Дата:
> explain select * from a where x=3;

PostgreSQL is treating 3 as an int4 (integer) type, whereas x is an int2
(smallint) type. Try casting the constant as a smallint and it should use
the index:

explain select * from a where x=3::smallint;

Greg

----- Original Message -----
From: "Dmitry Tkach" <dmitry@openratings.com>
To: <pgsql-general@postgresql.org.pgsql-sql@postgresql.org>
Sent: Friday, March 15, 2002 2:07 PM
Subject: [GENERAL] Why is it not using an index?


> This must be really simple, but I just can't get it :-(
> I have a table (a) with a single column (x):
>
>            Table "a"
>   Attribute |   Type   | Modifier
> -----------+----------+----------
>   x         | smallint |
> Index: a_idx
>
>
>     Index "a_idx"
>   Attribute |   Type
> -----------+----------
>   x         | smallint
> btree
>
> The table has 10000000 rows....
>
> Now, how come, when I do:
>
> explain select * from a where x=3;
>
> it says:
>
> Seq Scan on bset  (cost=100000000.00..100175934.05 rows=303 width=2)
>
> Why is it not using a_idx???
>
> I even tried set enable_seqscan to off - makes no difference :-(
>
> Any idea what is going on?
>
> Thanks a lot!
>
> Dima
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/users-lounge/docs/faq.html
>


Re: Why is it not using an index?

От
Dmitry Tkach
Дата:
Gregory Wood wrote:<br /><blockquote cite="mid:002801c1cc4f$25dba980$7889ffcc@comstock.com" type="cite"><blockquote
type="cite"><prewrap="">explain select * from a where x=3;<br /></pre></blockquote><pre wrap=""><br />PostgreSQL is
treating3 as an int4 (integer) type, whereas x is an int2<br />(smallint) type. Try casting the constant as a smallint
andit should use<br />the index:<br /><br />explain select * from a where x=3::smallint;<br /><br /></pre></blockquote>
Aha! Great! Thanks a lot! That worked!<br /> Now, the next problem:<br /><br /> explain select count (x) from a ;<br
/><br/> Aggregate  (cost=100175934.05..100175934.05 rows=1 width=2)<br />   ->  Seq Scan on a 
(cost=100000000.00..100150659.04rows=10110004 width=2)<br /><br /> Am I missing something here again, or will it just
notuse an index for aggregation?<br /><br /> I mean, especially an this case, it looks so weird that it KNOWS the
answerto my query RIGHT AWAY (rows=... in the explain response), yet it takes it so long to return it...<br /><br /><br
/><br/> 

Re: Why is it not using an index?

От
"Gregory Wood"
Дата:
> Am I missing something here again, or will it just not use an index for
aggregation?

PostgreSQL does not use an index to perform a full table count. I'm not sure
of the exact reasoning behind this, but I think there are multiple issues
with the approach.

> I mean, especially an this case, it looks so weird that it KNOWS the
answer to my query RIGHT AWAY (rows=... in the explain response), yet it
takes it so long to return it...

Actually, that rows= count is the *estimate* for the number of rows. That
estimate is calculated from a variety of statistics compiled when the
ANALYZE command is performed. Those statistics may or may not be up to date,
and are only used to plan the query's execution.

Greg


----- Original Message -----
From: Dmitry Tkach
To: Gregory Wood
Cc: PostgreSQL-General
Sent: Friday, March 15, 2002 3:01 PM
Subject: Re: [GENERAL] Why is it not using an index?


Gregory Wood wrote:

explain select * from a where x=3;
PostgreSQL is treating 3 as an int4 (integer) type, whereas x is an
int2(smallint) type. Try casting the constant as a smallint and it should
usethe index:explain select * from a where x=3::smallint;
Aha!  Great! Thanks a lot! That worked!
Now, the next problem:

explain select count (x) from a ;

Aggregate  (cost=100175934.05..100175934.05 rows=1 width=2)
  ->  Seq Scan on a  (cost=100000000.00..100150659.04 rows=10110004 width=2)

Am I missing something here again, or will it just not use an index for
aggregation?

I mean, especially an this case, it looks so weird that it KNOWS the answer
to my query RIGHT AWAY (rows=... in the explain response), yet it takes it
so long to return it...


Re: Why is it not using an index?

От
Jean-Luc Lachance
Дата:
Really, the PostgreSQL interpreter should be smart enough to figure this
out by itself...


Gregory Wood wrote:
>
> > explain select * from a where x=3;
>
> PostgreSQL is treating 3 as an int4 (integer) type, whereas x is an int2
> (smallint) type. Try casting the constant as a smallint and it should use
> the index:
>
> explain select * from a where x=3::smallint;
>
> Greg
>
> ----- Original Message -----
> From: "Dmitry Tkach" <dmitry@openratings.com>
> To: <pgsql-general@postgresql.org.pgsql-sql@postgresql.org>
> Sent: Friday, March 15, 2002 2:07 PM
> Subject: [GENERAL] Why is it not using an index?
>
> > This must be really simple, but I just can't get it :-(
> > I have a table (a) with a single column (x):
> >
> >            Table "a"
> >   Attribute |   Type   | Modifier
> > -----------+----------+----------
> >   x         | smallint |
> > Index: a_idx
> >
> >
> >     Index "a_idx"
> >   Attribute |   Type
> > -----------+----------
> >   x         | smallint
> > btree
> >
> > The table has 10000000 rows....
> >
> > Now, how come, when I do:
> >
> > explain select * from a where x=3;
> >
> > it says:
> >
> > Seq Scan on bset  (cost=100000000.00..100175934.05 rows=303 width=2)
> >
> > Why is it not using a_idx???
> >
> > I even tried set enable_seqscan to off - makes no difference :-(
> >
> > Any idea what is going on?
> >
> > Thanks a lot!
> >
> > Dima
> >
> >
> > ---------------------------(end of broadcast)---------------------------
> > TIP 5: Have you checked our extensive FAQ?
> >
> > http://www.postgresql.org/users-lounge/docs/faq.html
> >
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/users-lounge/docs/faq.html

Re: Why is it not using an index?

От
"Gregory Wood"
Дата:
It should be. I think the response you'll get from the people on this list
is that they're happy to accept a patch...

Greg

----- Original Message -----
From: "Jean-Luc Lachance" <jllachan@nsd.ca>
To: "Gregory Wood" <gregw@com-stock.com>
Cc: "Dmitry Tkach" <dmitry@openratings.com>; "PostgreSQL-General"
<pgsql-general@postgresql.org>
Sent: Friday, March 15, 2002 3:25 PM
Subject: Re: [GENERAL] Why is it not using an index?


> Really, the PostgreSQL interpreter should be smart enough to figure this
> out by itself...
>
>
> Gregory Wood wrote:
> >
> > > explain select * from a where x=3;
> >
> > PostgreSQL is treating 3 as an int4 (integer) type, whereas x is an int2
> > (smallint) type. Try casting the constant as a smallint and it should
use
> > the index:
> >
> > explain select * from a where x=3::smallint;
> >
> > Greg
> >
> > ----- Original Message -----
> > From: "Dmitry Tkach" <dmitry@openratings.com>
> > To: <pgsql-general@postgresql.org.pgsql-sql@postgresql.org>
> > Sent: Friday, March 15, 2002 2:07 PM
> > Subject: [GENERAL] Why is it not using an index?
> >
> > > This must be really simple, but I just can't get it :-(
> > > I have a table (a) with a single column (x):
> > >
> > >            Table "a"
> > >   Attribute |   Type   | Modifier
> > > -----------+----------+----------
> > >   x         | smallint |
> > > Index: a_idx
> > >
> > >
> > >     Index "a_idx"
> > >   Attribute |   Type
> > > -----------+----------
> > >   x         | smallint
> > > btree
> > >
> > > The table has 10000000 rows....
> > >
> > > Now, how come, when I do:
> > >
> > > explain select * from a where x=3;
> > >
> > > it says:
> > >
> > > Seq Scan on bset  (cost=100000000.00..100175934.05 rows=303 width=2)
> > >
> > > Why is it not using a_idx???
> > >
> > > I even tried set enable_seqscan to off - makes no difference :-(
> > >
> > > Any idea what is going on?
> > >
> > > Thanks a lot!
> > >
> > > Dima
> > >
> > >
> > > ---------------------------(end of
broadcast)---------------------------
> > > TIP 5: Have you checked our extensive FAQ?
> > >
> > > http://www.postgresql.org/users-lounge/docs/faq.html
> > >
> >
> > ---------------------------(end of broadcast)---------------------------
> > TIP 5: Have you checked our extensive FAQ?
> >
> > http://www.postgresql.org/users-lounge/docs/faq.html
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster
>


Re: Why is it not using an index?

От
Stephan Szabo
Дата:
On Fri, 15 Mar 2002, Dmitry Tkach wrote:

> explain select count (x) from a ;
>
> Aggregate� (cost=100175934.05..100175934.05 rows=1 width=2)
> � ->� Seq Scan on a� (cost=100000000.00..100150659.04 rows=10110004 width=2)
>
> Am I missing something here again, or will it just not use an index
> for aggregation?

It won't for something like the above because it needs to test each row
to see if it's currently visible to your transaction (which involves
reading from the table file anyway) which means you end up reading the
entire table plus the index (and paying some costs in random access).
If the index had the transaction information the index would be usable
but there are issues about doing that as well (you might want to check
past messages - especially ones from Tom Lane - on the subject)



Re: Why is it not using an index?

От
Tom Lane
Дата:
"Gregory Wood" <gregw@com-stock.com> writes:
> It should be. I think the response you'll get from the people on this list
> is that they're happy to accept a patch...

It's not as easy as you might think to come up with a general-purpose
solution --- bearing in mind that Postgres is supposed to support an
extensible set of datatypes, and so we'd prefer not to hard-wire much
knowledge of specific datatypes into the parser.

If you look back a year or two in the pghackers archives, you'll find
previous discussions and failed solution proposals.  It's still on the
TODO list, and eventually someone will come up with a usable answer.

            regards, tom lane

Re: Why is it not using an index?

От
Sergio Freue
Дата:
I had the same problem and the question was answered here yesterday:

>
> explain select * from a where x=3;
>

Try


explain select * from a where x=3::smallint;



That should do it. I opted for changing all indexed SMALLINT fields to
INTEGER.


Re: Why is it not using an index?

От
Martijn van Oosterhout
Дата:
On Fri, Mar 15, 2002 at 03:25:47PM -0500, Jean-Luc Lachance wrote:
> Really, the PostgreSQL interpreter should be smart enough to figure this
> out by itself...

It is actually, if you put quotes around the number so it is explicitly
typed as 'unknown'. The interpreter will then accuratly match the type.
Without the quotes the number becomes int4 and so a whole promotion/type
hierarchy needs to be built to determine how to relate them.

Just put quotes around all your constants and all your problems are solved.

> Gregory Wood wrote:
> >
> > > explain select * from a where x=3;
> >
> > PostgreSQL is treating 3 as an int4 (integer) type, whereas x is an int2
> > (smallint) type. Try casting the constant as a smallint and it should use
> > the index:
> >
> > explain select * from a where x=3::smallint;
> >
> > Greg
> >
> > ----- Original Message -----
> > From: "Dmitry Tkach" <dmitry@openratings.com>
> > To: <pgsql-general@postgresql.org.pgsql-sql@postgresql.org>
> > Sent: Friday, March 15, 2002 2:07 PM
> > Subject: [GENERAL] Why is it not using an index?
> >
> > > This must be really simple, but I just can't get it :-(
> > > I have a table (a) with a single column (x):
> > >
> > >            Table "a"
> > >   Attribute |   Type   | Modifier
> > > -----------+----------+----------
> > >   x         | smallint |
> > > Index: a_idx
> > >
> > >
> > >     Index "a_idx"
> > >   Attribute |   Type
> > > -----------+----------
> > >   x         | smallint
> > > btree
> > >
> > > The table has 10000000 rows....
> > >
> > > Now, how come, when I do:
> > >
> > > explain select * from a where x=3;
> > >
> > > it says:
> > >
> > > Seq Scan on bset  (cost=100000000.00..100175934.05 rows=303 width=2)
> > >
> > > Why is it not using a_idx???
> > >
> > > I even tried set enable_seqscan to off - makes no difference :-(
> > >
> > > Any idea what is going on?
> > >
> > > Thanks a lot!
> > >
> > > Dima
> > >
> > >
> > > ---------------------------(end of broadcast)---------------------------
> > > TIP 5: Have you checked our extensive FAQ?
> > >
> > > http://www.postgresql.org/users-lounge/docs/faq.html
> > >
> >
> > ---------------------------(end of broadcast)---------------------------
> > TIP 5: Have you checked our extensive FAQ?
> >
> > http://www.postgresql.org/users-lounge/docs/faq.html
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster

--
Martijn van Oosterhout <kleptog@svana.org>   http://svana.org/kleptog/
> Ignorance continues to thrive when intelligent people choose to do
> nothing.  Speaking out against censorship and ignorance is the imperative
> of all intelligent people.

Yet another indexing issue.

От
"David Siebert"
Дата:
I am having issues with an Index.
Here is the query

SELECT * FROM phonecalls WHERE istatus = 0 AND (sfor = 'pat' OR
sfor='TECHIES') ORDER BY ipri DESC, dplaceddate;
I have tried '0' and jut plain 0 as well as type casting it with ::int4 .

Here is the index I think it should use.

CREATE INDEX phonecallspoll ON phonecalls USING btree (sfor varchar_ops,
istatus int4_ops);
But it is still doing a scan?

Any suggestions?
yes I have used Vacumme with the anylise option.
Thanks for any info.


Re: Yet another indexing issue.

От
Stephan Szabo
Дата:
On Tue, 19 Mar 2002, David Siebert wrote:

>
> I am having issues with an Index.
> Here is the query
>
> SELECT * FROM phonecalls WHERE istatus = 0 AND (sfor = 'pat' OR
> sfor='TECHIES') ORDER BY ipri DESC, dplaceddate;
> I have tried '0' and jut plain 0 as well as type casting it with ::int4 .
>
> Here is the index I think it should use.
>
> CREATE INDEX phonecallspoll ON phonecalls USING btree (sfor varchar_ops,
> istatus int4_ops);
> But it is still doing a scan?
>
> Any suggestions?
> yes I have used Vacumme with the anylise option.

What is the schema (probably not meaningful but always helps), what does
explain show for the query (specifically for the row counds), does using
set enable_seqscan=off change the explain output?



Re: Yet another indexing issue.

От
"David Siebert"
Дата:
Here is the explain output

Sort  (cost=293.24..293.24 rows=1 width=128)
  ->  Seq Scan on phonecalls  (cost=0.00..293.23 rows=1 width=128)

Here is the Table
CREATE TABLE "phonecalls" (
  "irecnum" int4 DEFAULT nextval('"phonecalls_irecnum_seq"'::text) NOT NULL,
  "scaller" varchar(80),
  "sphone" varchar(40),
  "sphone2" varchar(40),
  "squedby" varchar(40),
  "sfor" varchar(40),
  "dplaceddate" timestamp,
  "dtakendate" timestamp,
  "dresdate" timestamp,
  "ipri" int4,
  "istatus" int4,
  "iresolution" int4,
  "ireques" int4,
  "snotes" varchar(3999),
  "stakenby" varchar(40),
  CONSTRAINT "phonecalls_irecnum_key" UNIQUE ("irecnum")
);

Where would one find set enable_seqscan=off; in the docs?

-----Original Message-----
From: pgsql-general-owner@postgresql.org
[mailto:pgsql-general-owner@postgresql.org]On Behalf Of Stephan Szabo
Sent: Tuesday, March 19, 2002 3:51 PM
To: David Siebert
Cc: pgsql-general@postgresql.org
Subject: Re: [GENERAL] Yet another indexing issue.


On Tue, 19 Mar 2002, David Siebert wrote:

>
> I am having issues with an Index.
> Here is the query
>
> SELECT * FROM phonecalls WHERE istatus = 0 AND (sfor = 'pat' OR
> sfor='TECHIES') ORDER BY ipri DESC, dplaceddate;
> I have tried '0' and jut plain 0 as well as type casting it with ::int4 .
>
> Here is the index I think it should use.
>
> CREATE INDEX phonecallspoll ON phonecalls USING btree (sfor varchar_ops,
> istatus int4_ops);
> But it is still doing a scan?
>
> Any suggestions?
> yes I have used Vacumme with the anylise option.

What is the schema (probably not meaningful but always helps), what does
explain show for the query (specifically for the row counds), does using
set enable_seqscan=off change the explain output?



---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

http://www.postgresql.org/users-lounge/docs/faq.html


Re: Yet another indexing issue.

От
Stephan Szabo
Дата:
On Tue, 19 Mar 2002, David Siebert wrote:

> Here is the explain output
>
> Sort  (cost=293.24..293.24 rows=1 width=128)
>   ->  Seq Scan on phonecalls  (cost=0.00..293.23 rows=1 width=128)
>
> Here is the Table
> CREATE TABLE "phonecalls" (
>   "irecnum" int4 DEFAULT nextval('"phonecalls_irecnum_seq"'::text) NOT NULL,
>   "scaller" varchar(80),
>   "sphone" varchar(40),
>   "sphone2" varchar(40),
>   "squedby" varchar(40),
>   "sfor" varchar(40),
>   "dplaceddate" timestamp,
>   "dtakendate" timestamp,
>   "dresdate" timestamp,
>   "ipri" int4,
>   "istatus" int4,
>   "iresolution" int4,
>   "ireques" int4,
>   "snotes" varchar(3999),
>   "stakenby" varchar(40),
>   CONSTRAINT "phonecalls_irecnum_key" UNIQUE ("irecnum")
> );
>

> Where would one find set enable_seqscan=off; in the docs?

To be honest I'm not sure where it's mentioned.  It's a big tool that
lets you make some gross changes to the optimizer's planning (sets the
cost of sequence scan very very high).

Does doing it before the explain change the output?

Also, does making an index on phonecalls(istatus, sfor) [rather than
sfor,istatus] change the choice?


Re: Yet another indexing issue.

От
"Pirtea Calin"
Дата:
> > Where would one find set enable_seqscan=off; in the docs?
>
> To be honest I'm not sure where it's mentioned.  It's a big tool that
> lets you make some gross changes to the optimizer's planning (sets the
> cost of sequence scan very very high).
>
I found this in Admin.pdf
3.4.1. Planner and Optimizer Tuning
page 37/38
ENABLE_SEQSCAN (boolean)
    Enables or disables the query planner's use of sequential scan plan
types. It's not possible to
suppress sequential scans entirely, but turning this variable off
discourages the planner from using
one if there is any other method available. The default is on. This is
mostly useful to debug the
query planner.

--
Best regards,
Aplication Developer
Pirtea Calin Iancu
S.C. SoftScape S.R.L.
pcalin@rdsor.ro


Re: Yet another indexing issue.

От
"David Siebert"
Дата:
Thank you. I found the error. It was the order of the fields in the index.
I do not rember seeing that the order made a difference in the indexing. It
is logical now that I think of it.
I for the life of me could not find where in PgAdminII I could set the order
of the fields in when creating an index so I did it by hand.
Thanks again.

-----Original Message-----
From: pgsql-general-owner@postgresql.org
[mailto:pgsql-general-owner@postgresql.org]On Behalf Of Pirtea Calin
Sent: Friday, March 22, 2002 9:38 AM
To: pgsql-general@postgresql.org
Subject: Re: [GENERAL] Yet another indexing issue.


> > Where would one find set enable_seqscan=off; in the docs?
>
> To be honest I'm not sure where it's mentioned.  It's a big tool that
> lets you make some gross changes to the optimizer's planning (sets the
> cost of sequence scan very very high).
>
I found this in Admin.pdf
3.4.1. Planner and Optimizer Tuning
page 37/38
ENABLE_SEQSCAN (boolean)
    Enables or disables the query planner's use of sequential scan plan
types. It's not possible to
suppress sequential scans entirely, but turning this variable off
discourages the planner from using
one if there is any other method available. The default is on. This is
mostly useful to debug the
query planner.

--
Best regards,
Aplication Developer
Pirtea Calin Iancu
S.C. SoftScape S.R.L.
pcalin@rdsor.ro


---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

http://www.postgresql.org/users-lounge/docs/faq.html


View INSERTs not returning OID in Postgres 7.2.1

От
Damon Cokenias
Дата:
I recently moved from 7.1.3 to 7.2.1.  In doing so, my application broke.  It relies on INSERT returning the OID of the
insertedrow, even if the INSERT was on a view.  I saw a note in the 7.2.1 notes about fixing a problem in this area,
perhapsmore needs to be done? 

Example:

acropolis=# create table shad (a integer);
CREATE
acropolis=# create view shadview as select * from shad;
CREATE
acropolis=# create rule shadview_insert as on insert to shadview do instead insert into shad values (new.a);
CREATE

acropolis=# insert into shad values (1);
INSERT 3876425 1

acropolis=# insert into shadview values (2);
INSERT 0 0

acropolis=# select * from shad;
 a
---
 1
 2
(2 rows)

---------------

Shouldn't the second INSERT return an OID as well?

Thanks,

-Damon

Re: View INSERTs not returning OID in Postgres 7.2.1

От
Tom Lane
Дата:
Damon Cokenias <lists@mtn-palace.com> writes:
> I recently moved from 7.1.3 to 7.2.1.  In doing so, my application
> broke.  It relies on INSERT returning the OID of the inserted row,
> even if the INSERT was on a view.

I'm afraid you were relying on a coincidental artifact of the old
implementation, namely that you got back the command tag associated
with the last command to be physically executed.  The current code
is careful to return the command tag associated with the original
query (here, the insert into shadview) regardless of execution order
of additional queries executed by rules.  I'm not sure that we can fix
your problem without breaking other cases.

            regards, tom lane