X-Original-To: pgsql-performance-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id 3260352B7F for ; Mon, 1 Aug 2005 01:05:04 -0300 (ADT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 63398-06 for ; Mon, 1 Aug 2005 04:04:55 +0000 (GMT) Received: from outbound.mailhop.org (outbound.mailhop.org [63.208.196.171]) by svr1.postgresql.org (Postfix) with ESMTP id 812C052AC2 for ; Mon, 1 Aug 2005 01:04:53 -0300 (ADT) Received: from ppp-66-143-176-222.dsl.austtx.swbell.net ([66.143.176.222] helo=mail.herk.net) by outbound.mailhop.org with esmtpsa (TLSv1:DES-CBC3-SHA:168) (Exim 4.51) id 1DzRXn-000Bll-SZ for pgsql-performance@postgresql.org; Mon, 01 Aug 2005 00:04:52 -0400 Received: from localhost (localhost [127.0.0.1]) (uid 500) by mail.herk.net with local; Sun, 31 Jul 2005 23:04:49 -0500 id 00114186.42ED9F61.00001AB0 X-Mail-Handler: MailHop Outbound by DynDNS.org X-Originating-IP: 66.143.176.222 X-Report-Abuse-To: abuse@dyndns.org (see http://www.mailhop.org/outbound/abuse.html for abuse reporting information) X-MHO-User: parkerm Date: Sun, 31 Jul 2005 23:04:49 -0500 From: Michael Parker To: pgsql-performance@postgresql.org Subject: Re: Performance problems testing with Spamassassin 3.1.0 Message-ID: <20050801040443.GA6527@mail.herk.net> References: <42E80C28.2040608@aptalaska.net> <1122532023.25574.1.camel@localhost.localdomain> <42E9749F.6000709@aptalaska.net> <1122616211.5691.340.camel@lamb.mcmillan.net.nz> <42EA6966.8090402@aptalaska.net> <1122668371.5691.352.camel@lamb.mcmillan.net.nz> <19405.1122670917@sss.pgh.pa.us> <42EAA410.9010700@aptalaska.net> <27897.1122748133@sss.pgh.pa.us> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="=_mail-6832-1122869089-0001-2" Content-Disposition: inline In-Reply-To: <27897.1122748133@sss.pgh.pa.us> User-Agent: Mutt/1.5.1i X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.05 tagged_above=0 required=5 tests=FORGED_RCVD_HELO X-Spam-Level: X-Archive-Number: 200508/1 X-Sequence-Number: 13748 This is a MIME-formatted message. If you see this text it means that your E-mail software does not support MIME-formatted messages. --=_mail-6832-1122869089-0001-2 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi All, As a SpamAssassin developer, who by my own admission has real problem getting PostgreSQL to work well, I must thank everyone for their feedback on this issue. Believe me when I say what is in the tree now is a far cry from what used to be there, orders of magnitude faster for sure. I think there are several good ideas that have come out of this thread and I've set about attempting to implement them. Here is a version of the stored procedure, based in large part by the one written by Tom Lane, that accepts and array of tokens and loops over them to either update or insert them into the database (I'm not including the greatest_int/least_int procedures but you've all seen them before): CREATE OR REPLACE FUNCTION put_tokens(inuserid INTEGER, intokenary BYTEA[], inspam_count INTEGER, inham_count INTEGER, inatime INTEGER) RETURNS VOID AS '=20 DECLARE _token BYTEA; new_tokens INTEGER :=3D 0; BEGIN for i in array_lower(intokenary, 1) .. array_upper(intokenary, 1) LOOP _token :=3D intokenary[i]; UPDATE bayes_token SET spam_count =3D greatest_int(spam_count + inspam_count, 0), ham_count =3D greatest_int(ham_count + inham_count, 0), atime =3D greatest_int(atime, inatime) WHERE id =3D inuserid=20 AND token =3D _token;=20 IF NOT FOUND THEN=20 -- we do not insert negative counts, just return true IF NOT (inspam_count < 0 OR inham_count < 0) THEN INSERT INTO bayes_token (id, token, spam_count, ham_count, atime)=20 VALUES (inuserid, _token, inspam_count, inham_count, inatime);=20 IF FOUND THEN new_tokens :=3D new_tokens + 1; END IF; END IF; END IF; END LOOP; UPDATE bayes_vars SET token_count =3D token_count + new_tokens, newest_token_age =3D greatest_int(newest_token_age, inatime), oldest_token_age =3D least_int(oldest_token_age, inatime) WHERE id =3D inuserid; RETURN; END;=20 ' LANGUAGE 'plpgsql';=20 This version is about 32x faster than the old version, with the default fsync value and autovacuum running in the background. The next hurdle, and I've just posted to the DBD::Pg list, is escaping/quoting the token strings. They are true binary strings, substrings of SHA1 hashes, I don't think the original data set provided puts them in the right context. They have proved to be tricky. I'm unable to call the stored procedure from perl because I keep getting a malformed array litteral error. Here is some example code that shows the issue: #!/usr/bin/perl -w # from a new db, do this first # INSERT INTO bayes_vars VALUES (1,'nobody',0,0,0,0,0,0,2147483647,0); use strict; use DBI; use DBD::Pg qw(:pg_types); use Digest::SHA1 qw(sha1); my $dbh =3D DBI->connect("DBI:Pg:dbname=3Dspamassassin","postgres") || die; my @dataary; # Input is just a list of words (ie /usr/share/dict/words) stop after 150 while(<>) { chomp; push(@dataary, substr(sha1($_), -5)); # to see it work with normal string comment out above and uncomment below # push(@dataary, $_); last if scalar(@dataary) >=3D 150; } my $datastring =3D join(",", map { '"' . bytea_esc($_) . '"' } @dataary); my $sql =3D "select put_tokens(1, '{$datastring}', 1, 1, 10000)"; my $sth =3D $dbh->prepare($sql); my $rc =3D $sth->execute(); unless ($rc) { print "Error: " . $dbh->errstr() . "\n"; } $sth->finish(); sub bytea_esc { my ($str) =3D @_; my $buf =3D ""; foreach my $char (split(//,$str)) { if (ord($char) =3D=3D 0) { $buf .=3D "\\\\000"; } elsif (ord($char) =3D=3D 39) { $buf .=3D "\\\\047"; } elsif (ord($char) =3D=3D 92) { $buf .=3D "\\\\134"; } else { $buf .=3D $char; } } return $buf; } Any ideas? or thoughts on the revised procedure? I'd greatly appriciate them. Sorry for the length, but hopefully it give a good enough example. Thanks Michael Parker --=_mail-6832-1122869089-0001-2 Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQFC7Z9bG4km+uS4gOIRAklxAJ918GyBQKOnrblMY24M3GIsiVXjWQCfafn5 K2WAqkOXTbmL9oLtY5UkchE= =FGrI -----END PGP SIGNATURE----- --=_mail-6832-1122869089-0001-2--