X-Original-To: pgsql-admin@postgresql.org Received: from localhost (developer.postgresql.org [64.117.224.193]) by developer.postgresql.org (Postfix) with ESMTP id 611F0925C5A for ; Thu, 29 May 2003 10:26:53 -0400 (EDT) Received: from developer.postgresql.org ([64.117.224.193]) by localhost (developer.postgresql.org [64.117.224.193:10024]) (amavisd-new) with ESMTP id 68735-08 for ; Thu, 29 May 2003 10:26:51 -0400 (EDT) Received: from sss.pgh.pa.us (unknown [192.204.191.242]) by developer.postgresql.org (Postfix) with ESMTP id 79CC9925C4A for ; Thu, 29 May 2003 10:26:51 -0400 (EDT) Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) by sss.pgh.pa.us (8.12.9/8.12.9) with ESMTP id h4TEQiU6017483; Thu, 29 May 2003 10:26:44 -0400 (EDT) To: Robert.Farrugia@go.com.mt Cc: pgsql-admin@postgresql.org Subject: Re: After VACUUM, statistics become skewed In-reply-to: <20030529122409.80298925C1F@developer.postgresql.org> References: <20030529122409.80298925C1F@developer.postgresql.org> Comments: In-reply-to Robert.Farrugia@go.com.mt message dated "Thu, 29 May 2003 14:24:06 +0200" Date: Thu, 29 May 2003 10:26:43 -0400 Message-ID: <17482.1054218403@sss.pgh.pa.us> From: Tom Lane X-Virus-Scanned: by amavisd-new X-Archive-Number: 200305/400 X-Sequence-Number: 8962 Robert.Farrugia@go.com.mt writes: > The definitions of the indexes are: > mo_200302_calling_idx uses (answertime::timestamp, > callingnumber_type::char(1), callingnumber_value::varchar) in this order > mo_200302_called_idx uses (answertime::timestamp, > callednumber_type::char(1), callednumber_value::varchar) in this order > If I am understanding you well, the planner may ignore the index if the OR > clause uses the second or third column of a multi-column index, even > though the first column is used. Is there a way to force the planner to > use a particular index ? In this particular case the problem is that the planner does not believe the index is applicable. The only way to make it think that is to change the query or the index definition so that the OR clause (i.e., the IN) contains references to the first index column. For example, you could rewrite your query from its current effective form: select ... where answertime between '2003/2/3 00:00:00' and '2003/2/14 23:59:59' and dialleddigits_value = '50043992' and (callednumber_type = 'P' or callednumber_type = 'M') to something like select ... where (answertime between '2003/2/3 00:00:00' and '2003/2/14 23:59:59' and dialleddigits_value = '50043992' and callednumber_type = 'P') OR (answertime between '2003/2/3 00:00:00' and '2003/2/14 23:59:59' and dialleddigits_value = '50043992' and callednumber_type = 'M') which can be used for two indexscans on the first two columns of mo_200302_called_idx. (BTW, if this is a frequent query, maybe you should have an index that includes dialleddigits_value as the third column?) You could factor out "and dialleddigits_value = '50043992'" or not here, that doesn't matter; but the OR'd-together subclauses have to all mention the leading term of the index, ie, answertime. Plan B would be to leave the query alone and change the index column order so that callednumber_type is first. This is probably not a great idea though, since answertime is a much better first key for most purposes. It's moderately annoying that the planner is not bright enough to figure out this transformation for itself. I suspect what is needed is a whole fresh look at the OR-index processing algorithm; it seems excessively complicated and yet it still doesn't do everything one would want. regards, tom lane