Received: from maia.hub.org (maia-5.hub.org [200.46.204.29]) by mail.postgresql.org (Postfix) with ESMTP id 4D9DE1337999 for ; Mon, 14 Feb 2011 04:05:07 -0400 (AST) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.29]) (amavisd-maia, port 10024) with ESMTP id 11340-04 for ; Mon, 14 Feb 2011 08:05:00 +0000 (UTC) X-Greylist: delayed 00:18:30.970064 by SQLgrey-1.7.6 Received: from wentylator.ang.com.pl (wentylator.ang.com.pl [89.174.215.202]) by mail.postgresql.org (Postfix) with ESMTP id 846841336B42 for ; Mon, 14 Feb 2011 04:04:59 -0400 (AST) Received: from Artur7 (cfidsl [83.18.105.226]) by wentylator.ang.com.pl (Postfix) with ESMTP id 6314C2DD299; Mon, 14 Feb 2011 08:38:49 +0100 (CET) From: =?iso-8859-2?Q?Artur_Zaj=B1c?= To: , "'Richard Huxton'" Cc: References: <004601cbcc14$acfe99d0$06fbcd70$@com> <4D58D752.2000100@archonet.com> <004701cbcc18$c54c8980$4fe59c80$@com> In-Reply-To: <004701cbcc18$c54c8980$4fe59c80$@com> Subject: Re: How to boost performance of queries containing pattern matching characters Date: Mon, 14 Feb 2011 08:38:48 +0100 Message-ID: <003801cbcc1a$37d2f7e0$a778e7a0$@ang.com.pl> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Thread-Index: AQJMtgQYv5PXiwGLv3AG4jOO/Eh+PwFEXM31AMeiMN6S7mhmAA== Content-Language: pl X-wentylator-MailScanner-Information: Please contact the ISP for more information X-wentylator-MailScanner: Found to be clean X-wentylator-MailScanner-SpamCheck: not spam, SpamAssassin (cached, score=0, required 6, autolearn=not spam) X-wentylator-MailScanner-From: azajac@ang.com.pl X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.91 tagged_above=-10 required=5 tests=BAYES_00=-1.9, T_RP_MATCHES_RCVD=-0.01 X-Spam-Level: X-Archive-Number: 201102/377 X-Sequence-Number: 42515 >How can we boost performance of queries containing pattern matching >characters? In my case, we're using a percent sign (%) that matches any string of zero or more characters. > > QUERY: DELETE FROM MYTABLE WHERE EMAIL ILIKE '%domain.com%' > > EMAIL column is VARCHAR(256). > > As it is clear from the above query, email is matched "partially and case-insensitively", which my application requirement demands. > > In case, if it were a full match, I could easily define a functional > INDEX on EMAIL column (lower(EMAIL)) and I could rewrite my DELETE where criteria like lower(EMAIL) = 'someemail@domain.com'. > > MYTABLE currently contains 2 million records and grows consistently. I had almost the same problem. To resolve it, I created my own text search parser (myftscfg) which divides text in column into three letters parts, for example: someemail@domain.com is divided to som, ome,mee,eem,ema,mai,ail,il@, l@d,@do,dom,oma,mai,ain,in.,n.c,.co,com There should be also index on email column: CREATE INDEX "email _fts" on mytable using gin (to_tsvector('myftscfg'::regconfig, email)) Every query like email ilike '%domain.com%' should be rewrited to: WHERE to_tsvector('myftscfg',email) @@ to_tsquery('dom') AND to_tsvector('myftscfg',email) @@ to_tsquery('oma') AND to_tsvector('myftscfg',email) @@ to_tsquery('mai') AND to_tsvector('myftscfg',email) @@ to_tsquery('ain') AND to_tsvector('myftscfg',email) @@ to_tsquery('in.') AND to_tsvector('myftscfg',email) @@ to_tsquery('n.c') AND to_tsvector('myftscfg',email) @@ to_tsquery('.co') AND to_tsvector('myftscfg',email) @@ to_tsquery('com') AND email ILIKE '%domain.com%'; Index is reducing number of records and clause email ILIKE '%domain.com%' is selecting only valid records. I didn't found better solution. ------------------------------------------- Artur Zajac