X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [64.117.224.130]) by svr1.postgresql.org (Postfix) with ESMTP id A7813D1C7EF for ; Wed, 6 Aug 2003 15:12:42 +0000 (GMT) Received: from svr1.postgresql.org ([64.117.224.193]) by localhost (neptune.hub.org [64.117.224.130]) (amavisd-new, port 10024) with ESMTP id 38429-09 for ; Wed, 6 Aug 2003 12:11:20 -0300 (ADT) Received: from valis.advance.net (valis.advance.net [208.217.108.87]) by svr1.postgresql.org (Postfix) with ESMTP id 185E1D1C50A for ; Wed, 6 Aug 2003 12:12:31 -0300 (ADT) Received: from advance.net (valis.advance.net [127.0.0.1]) by valis.advance.net (8.11.2/8.11.2) with ESMTP id h76FCv326836 for ; Wed, 6 Aug 2003 11:12:57 -0400 Message-ID: <3F311AF8.5080707@advance.net> Date: Wed, 06 Aug 2003 11:12:56 -0400 From: Andrew Droffner User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.1b) Gecko/20020722 X-Accept-Language: en-us, en MIME-Version: 1.0 To: pgsql-sql@postgresql.org Subject: User-defined SQL function has slower query on 7.3.3 than 7.1.3 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: by amavisd-new at postgresql.org X-Archive-Number: 200308/55 X-Sequence-Number: 14671 I have this QUERY (below) that PostgreSQL 7.3.X servers run MUCH slower than the 7.1.3 server does. It makes sense that both servers have to do a sequential scan over the ZIPCODE column. There are over 7,500 rows in the LOCATIONS table. Does anyone know what changed in the planner or optimizer? Can I change the postgresql.conf file to improve 7.3.3 performance? Situation --------- Here is the situation... PG 7.1.3 returns QUERY in about 4 seconds. The EXPLAIN plan says it uses the index on country. PG 7.3.3 simply does not return QUERY. I've waited over 3 minutes. With the extra condition WHERE STATE = 'NJ' it takes almost 5 seconds. Other states are much worse. QUERY ----- SELECT ZIPCODE FROM LOCATIONS WHERE COUNTRY = 'USA' AND ZIP_DIST_MI('07306', ZIPCODE) <= 25; The function is written in C, using SPI. Given two US ZIP codes, it returns the distance in miles. For example, it is 78 miles from Jersey City to Philadelphia: db=> select ZIP_DIST_MI('07306', '19130'); zip_dist_mi ----------------- 78.801595557406 (1 row) ZIP_DIST_MI() uses a geo_zipdata table to get the latitude and longitude. Using those, it can calculate the "great circle distance" between ZIPs with C double arithmetic. It finds the ZIPs locations with a prepared (and saved) SPI query, which uses an index: "select latitude, longitude from geo_zipdata where zip = $1" FUNCTION -------- CREATE FUNCTION ZIP_DIST_MI(TEXT, TEXT) RETURNS DOUBLE PRECISION... ZIP DATA TABLE -------------- CREATE TABLE GEO_ZIPDATA ( ZIP VARCHAR(5) NOT NULL, STATE VARCHAR(2) NOT NULL, CITY VARCHAR(64) NOT NULL, COUNTY VARCHAR(64) NOT NULL, LATITUDE FLOAT NOT NULL, LONGITUDE FLOAT NOT NULL, FIPS NUMERIC(10) NOT NULL ); CREATE INDEX GEO_ZIPDATA_ZIP_IDX ON GEO_ZIPDATA (ZIP);