Received: from localhost (unknown [200.46.204.183]) by mail.postgresql.org (Postfix) with ESMTP id 6AB3664FD70 for ; Sun, 30 Nov 2008 16:42:39 -0400 (AST) Received: from mail.postgresql.org ([200.46.204.86]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 43986-09 for ; Sun, 30 Nov 2008 16:42:36 -0400 (AST) Received: from news.hub.org (news.hub.org [200.46.204.72]) by mail.postgresql.org (Postfix) with ESMTP id 2AB5C64FD31 for ; Sun, 30 Nov 2008 16:42:36 -0400 (AST) Received: from news.hub.org (news.hub.org [200.46.204.72]) by news.hub.org (8.14.1/8.14.1) with ESMTP id mAUKgWnS073823 for ; Sun, 30 Nov 2008 16:42:33 -0400 (AST) (envelope-from news@news.hub.org) Received: (from news@localhost) by news.hub.org (8.14.1/8.14.1/Submit) id mAUKJXLY051479 for pgsql-performance@postgresql.org; Sun, 30 Nov 2008 16:19:33 -0400 (AST) (envelope-from news) From: "Andrus" X-Newsgroups: pgsql.performance Subject: Seq scan over 3.3 millions of rows instead of using date and pattern indexes Date: Sun, 30 Nov 2008 22:17:34 +0200 Organization: Hub.Org Networking Services Lines: 97 Message-ID: Mime-Version: 1.0 Content-Type: text/plain; format=flowed; charset="windows-1257"; reply-type=original Content-Transfer-Encoding: 7bit X-Complaints-To: usenet@news.hub.org X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Windows Mail 6.0.6001.18000 X-MimeOLE: Produced By Microsoft MimeOLE V6.0.6001.18049 To: pgsql-performance@postgresql.org X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.316 tagged_above=0 required=5 tests=SARE_MILLIONSOF=0.315, STOX_REPLY_TYPE=0.001 X-Spam-Level: X-Archive-Number: 200811/305 X-Sequence-Number: 32036 explain analyze SELECT sum(1) FROM dok JOIN rid USING (dokumnr) WHERE dok.kuupaev>='2008-05-01' and ( ( dok.doktyyp IN ('V','G','Y','K','I','T','D','N','H','M','E','B','A','R','C','F','J','Q') AND CASE WHEN NOT dok.objrealt OR dok.doktyyp='I' THEN dok.yksus ELSE rid.kuluobjekt END LIKE 'AEGVIIDU%' ) OR ( dok.doktyyp IN ('O','S','I','U','D','P') AND CASE WHEN dok.objrealt THEN rid.kuluobjekt ELSE dok.sihtyksus END LIKE 'AEGVIIDU%' ) ) "Aggregate (cost=369240.67..369240.68 rows=1 width=0) (actual time=41135.557..41135.560 rows=1 loops=1)" " -> Hash Join (cost=96614.24..369229.39 rows=4508 width=0) (actual time=5859.704..40912.979 rows=59390 loops=1)" " Hash Cond: ("outer".dokumnr = "inner".dokumnr)" " Join Filter: (((("inner".doktyyp = 'V'::bpchar) OR ("inner".doktyyp = 'G'::bpchar) OR ("inner".doktyyp = 'Y'::bpchar) OR ("inner".doktyyp = 'K'::bpchar) OR ("inner".doktyyp = 'I'::bpchar) OR ("inner".doktyyp = 'T'::bpchar) OR ("inner".doktyyp = 'D'::bpchar) OR ("inner".doktyyp = 'N'::bpchar) OR ("inner".doktyyp = 'H'::bpchar) OR ("inner".doktyyp = 'M'::bpchar) OR ("inner".doktyyp = 'E'::bpchar) OR ("inner".doktyyp = 'B'::bpchar) OR ("inner".doktyyp = 'A'::bpchar) OR ("inner".doktyyp = 'R'::bpchar) OR ("inner".doktyyp = 'C'::bpchar) OR ("inner".doktyyp = 'F'::bpchar) OR ("inner".doktyyp = 'J'::bpchar) OR ("inner".doktyyp = 'Q'::bpchar)) AND (CASE WHEN ((NOT ("inner".objrealt)::boolean) OR ("inner".doktyyp = 'I'::bpchar)) THEN "inner".yksus ELSE "outer".kuluobjekt END ~~ 'AEGVIIDU%'::text)) OR ((("inner".doktyyp = 'O'::bpchar) OR ("inner".doktyyp = 'S'::bpchar) OR ("inner".doktyyp = 'I'::bpchar) OR ("inner".doktyyp = 'U'::bpchar) OR ("inner".doktyyp = 'D'::bpchar) OR ("inner".doktyyp = 'P'::bpchar)) AND (CASE WHEN ("inner".objrealt)::boolean THEN "outer".kuluobjekt ELSE "inner".sihtyksus END ~~ 'AEGVIIDU%'::text)))" " -> Seq Scan on rid (cost=0.00..129911.53 rows=3299853 width=18) (actual time=0.039..17277.888 rows=3299777 loops=1)" " -> Hash (cost=92983.97..92983.97 rows=336110 width=38) (actual time=3965.478..3965.478 rows=337455 loops=1)" " -> Bitmap Heap Scan on dok (cost=1993.66..92983.97 rows=336110 width=38) (actual time=135.810..2389.703 rows=337455 loops=1)" " Recheck Cond: (kuupaev >= '2008-05-01'::date)" " Filter: ((doktyyp = 'V'::bpchar) OR (doktyyp = 'G'::bpchar) OR (doktyyp = 'Y'::bpchar) OR (doktyyp = 'K'::bpchar) OR (doktyyp = 'I'::bpchar) OR (doktyyp = 'T'::bpchar) OR (doktyyp = 'D'::bpchar) OR (doktyyp = 'N'::bpchar) OR (doktyyp = 'H'::bpchar) OR (doktyyp = 'M'::bpchar) OR (doktyyp = 'E'::bpchar) OR (doktyyp = 'B'::bpchar) OR (doktyyp = 'A'::bpchar) OR (doktyyp = 'R'::bpchar) OR (doktyyp = 'C'::bpchar) OR (doktyyp = 'F'::bpchar) OR (doktyyp = 'J'::bpchar) OR (doktyyp = 'Q'::bpchar) OR (doktyyp = 'O'::bpchar) OR (doktyyp = 'S'::bpchar) OR (doktyyp = 'I'::bpchar) OR (doktyyp = 'U'::bpchar) OR (doktyyp = 'D'::bpchar) OR (doktyyp = 'P'::bpchar))" " -> Bitmap Index Scan on dok_kuupaev_idx (cost=0.00..1993.66 rows=347618 width=0) (actual time=97.881..97.881 rows=337770 loops=1)" " Index Cond: (kuupaev >= '2008-05-01'::date)" "Total runtime: 41136.348 ms" 8.1.4 Db is analyzed, default_statistics_target is 40. PostgreSql still choices seq scan over rid. This query can optimized as follows: 1. kuupaev >= '2008-05-01' index can reduce number of scanned rows 10 times (to 330000) 2. AEGVIIDU% can reduce number of rows 6 times (to 60000) How to force pg to use indexes for those conditions ? This query can be executed against different shops groups (int this case there is other value than AEGVIIDU) and for different date. There are 6 different shop groups containing roughly same number or records each. So using index on AEGVIIDU% can decrease number of scanned rows 6 times. Usually 90% of dok records contain 'Y' in dok.doktyyp column and dok.objrealt is false for those records. Is it possible to use come functional index or other method to speed it ? rid.kuluobjekt, dok.yksus and dok.sihtyksus types are char(10). There are indexes dok(yksus bpchar_pattern_ops) dok(sihtyksus bpchar_pattern_ops) Is it possible to re-write query that it uses those indexes or create some other indexes? Using 8.1.4, us-en locale, utf-8 db encoding. select column list is removed from sample. Andrus.