Received: from localhost (maia-2.hub.org [200.46.204.187]) by postgresql.org (Postfix) with ESMTP id 7157A9FBA83 for ; Mon, 21 May 2007 01:36:01 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.187]) (amavisd-maia, port 10024) with ESMTP id 74991-03-7 for ; Mon, 21 May 2007 01:35:53 -0300 (ADT) X-Greylist: delayed 00:06:38.941979 by SQLgrey-1.7.4 Received: from k2smtpout04-02.prod.mesa1.secureserver.net (k2smtpout04-02.prod.mesa1.secureserver.net [64.202.189.173]) by postgresql.org (Postfix) with SMTP id 11B939FBAFE for ; Mon, 21 May 2007 01:35:35 -0300 (ADT) Received: (qmail 13136 invoked from network); 21 May 2007 04:28:55 -0000 Received: from unknown (HELO mail.servantwebhosting.com) (68.178.159.82) by k2smtpout04-02.prod.mesa1.secureserver.net (64.202.189.173) with ESMTP; 21 May 2007 04:28:55 -0000 Received: (qmail 1725 invoked by uid 2527); 20 May 2007 21:28:55 -0700 Received: from 70.64.210.50 by jonah.prod.phx1.secureserver.net (envelope-from , uid 2525) with qmail-scanner-1.25-st-qms (clamdscan: 0.86.2/989. spamassassin: 3.1.8. perlscan: 1.25-st-qms. Clear:RC:0(70.64.210.50):SA:0(1.4/5.0):. Processed in 2.787176 secs); 21 May 2007 04:28:55 -0000 X-Antivirus-MYDOMAIN-Mail-From: pgsql-performance@nullmx.com via jonah.prod.phx1.secureserver.net X-Antivirus-MYDOMAIN: 1.25-st-qms (Clear:RC:0(70.64.210.50):SA:0(1.4/5.0):. Processed in 2.787176 secs Process 1648) X-Envelope-From: pgsql-performance@nullmx.com Received: from s010600e0296eec95.mj.shawcable.net (HELO shach) (rob@nullmx.com@70.64.210.50) by mail.servantwebhosting.com with SMTP; 20 May 2007 21:28:52 -0700 Content-Disposition: inline From: "Chuck D." Reply-To: pgsql-performance@nullmx.com To: pgsql-performance@postgresql.org Subject: Rewriting DISTINCT and losing performance Date: Sun, 20 May 2007 22:28:30 -0600 User-Agent: KMail/1.9.5 MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <200705202228.32129.pgsql-performance@nullmx.com> X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200705/387 X-Sequence-Number: 24777 Hi all, I know we've covered this before but I'm having trouble with it today. I have some geographic data in tables that I'm working with. I have a country, state and city table. I was selecting the country_name out of the country table but discovered that some countries (like Antarctica) didn't have cities in the city table. I resolved to query the country table for only country_name's which had country_id's in the city table - meaning the country had cities listed. The problem was I had a couple different sources (in separate tables) with some extraneous column data so I chose to consolidate the city tables from the different sources and column data that I don't need because I don't have the hardware to support it. That was the end of my query time. Here's the original table and query: # \d geo.world_city Table "geo.world_city" Column | Type | Modifiers ------------+------------------------+----------- city_id | integer | not null state_id | smallint | country_id | smallint | rc | smallint | latitude | numeric(9,7) | longitude | numeric(10,7) | dsg | character(5) | cc1 | character(2) | adm1 | character(2) | city_name | character varying(200) | Indexes: "world_city_pk" PRIMARY KEY, btree (city_id) "idx_world_city_cc1" btree (cc1) "idx_world_city_cc1_adm1" btree (cc1, adm1) "idx_world_city_country_id" btree (country_id) "idx_world_city_name_first_letter" btree (state_id, "substring"(lower(city_name::text), 1, 1)) "idx_world_city_state_id" btree (state_id) explain analyze SELECT country_id, country_name FROM geo.country WHERE country_id IN (select country_id FROM geo.world_city) ; QUERY PLAN ----------------------------------------------------------------------------- -------------------------------------------------------------------------- Nested Loop IN Join (cost=0.00..167.97 rows=155 width=15) (actual time=85.502..3479.449 rows=231 loops=1) -> Seq Scan on country (cost=0.00..6.44 rows=244 width=15) (actual time=0.089..0.658 rows=244 loops=1) -> Index Scan using idx_world_city_country_id on world_city (cost=0.00..8185.05 rows=12602 width=2) (actual time=14.250..14.250 rows=1 loops=244) Index Cond: (country.country_id = world_city.country_id) Total runtime: 3479.921 ms Odd that it took 3 seconds because every previous run has been much quicker. The next run was: QUERY PLAN ----------------------------------------------------------------------------- ------------------------------------------------------------------------ Nested Loop IN Join (cost=0.00..167.97 rows=155 width=15) (actual time=0.087..6.967 rows=231 loops=1) -> Seq Scan on country (cost=0.00..6.44 rows=244 width=15) (actual time=0.028..0.158 rows=244 loops=1) -> Index Scan using idx_world_city_country_id on world_city (cost=0.00..8185.05 rows=12602 width=2) (actual time=0.026..0.026 rows=1 loops=244) Index Cond: (country.country_id = world_city.country_id) Total runtime: 7.132 ms (5 rows) But that was irrelevant. I created a new table and eliminated the data and it looks like this: # \d geo.city Table "geo.city" Column | Type | Modifiers ------------+------------------------+----------- city_id | integer | not null state_id | smallint | country_id | smallint | latitude | numeric(9,7) | longitude | numeric(10,7) | city_name | character varying(100) | Indexes: "city_pk" PRIMARY KEY, btree (city_id) "idx_city_country_id" btree (country_id) CLUSTER Foreign-key constraints: "city_state_id_fk" FOREIGN KEY (state_id) REFERENCES geo.state(state_id) ON UPDATE CASCADE ON DELETE CASCADE explain analyze SELECT country_id, country_name FROM geo.country WHERE country_id IN (select country_id FROM geo.city) ; -- won't complete in a reasonable amount of time. This one won't use the country_id index. The two tables have almost the same number of rows: cmi=# select count(*) from geo.world_city; count --------- 1953314 (1 row) cmi=# select count(*) from geo.city; count --------- 2122712 (1 row) I tried to force it and didn't see any improvement. I've vacuummed, analyzed, clustered. Can someone help me to get only the countries who have cities in the city table in a reasonable amount of time? -------------------------------------------------------