X-Original-To: pgsql-performance-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [64.117.224.130]) by svr1.postgresql.org (Postfix) with ESMTP id 35AB9D1C92F for ; Wed, 6 Aug 2003 20:36:45 +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 69550-09 for ; Wed, 6 Aug 2003 17:35:24 -0300 (ADT) Received: from sss.pgh.pa.us (unknown [192.204.191.242]) by svr1.postgresql.org (Postfix) with ESMTP id A10EDD1C4E3 for ; Wed, 6 Aug 2003 17:36:33 -0300 (ADT) Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) by sss.pgh.pa.us (8.12.9/8.12.9) with ESMTP id h76KaVSa007897; Wed, 6 Aug 2003 16:36:32 -0400 (EDT) To: Scott Cain Cc: pgsql-performance@postgresql.org Subject: Re: EXTERNAL storage and substring on long strings In-reply-to: <1059679600.1429.41.camel@localhost.localdomain> References: <1059679600.1429.41.camel@localhost.localdomain> Comments: In-reply-to Scott Cain message dated "31 Jul 2003 15:26:40 -0400" Date: Wed, 06 Aug 2003 16:36:31 -0400 Message-ID: <7896.1060202191@sss.pgh.pa.us> From: Tom Lane X-Virus-Scanned: by amavisd-new at postgresql.org X-Archive-Number: 200308/114 X-Sequence-Number: 2931 Scott Cain writes: > A few days ago, I asked for advice on speeding up substring queries on > the GENERAL mailing list. Joe Conway helpfully pointed out the ALTER > TABLE STORAGE EXTERNAL documentation. After doing the alter, > the queries got slower! Here is the background: Ah-hah, I've sussed it ... you didn't actually change the storage representation. You wrote: > Now, I'll change the storage: > alter table feature alter column residues set storage external; > To make sure that really happens, I run an update on feature: > update feature set residues = residues where feature_id<8; > and then VACUUM ANALYZE again. This sounds good --- in fact, I think we all just accepted it when we read it --- but in fact *that update didn't decompress the toasted data*. The tuple toaster sees that the same toasted value is being stored back into the row, and so it just re-uses the existing toasted data; it does not stop to notice that the column storage preference has changed. To actually get the storage to change, you need to feed the value through some function or operator that will decompress it. Then it won't get recompressed when it's stored. One easy way (since this is a text column) is update feature set residues = residues || '' where feature_id<8; To verify that something really happened, try doing VACUUM VERBOSE on the table before and after. The quoted number of tuples in the toast table should rise substantially. I did the following comparisons on the test data you made available, using two tables in which one has default storage and one has "external" (not compressed) storage: scott=# \timing Timing is on. scott=# select length (dna) from edna; length ----------- 245203899 (1 row) Time: 1.05 ms scott=# select length (dna) from ddna; length ----------- 245203899 (1 row) Time: 1.11 ms scott=# select length(substring(dna from 1000000 for 20000)) from edna; length -------- 20000 (1 row) Time: 30.43 ms scott=# select length(substring(dna from 1000000 for 20000)) from ddna; length -------- 20000 (1 row) Time: 37383.02 ms scott=# So it looks like the external-storage optimization for substring() does work as expected, once you get the data into the right format ... regards, tom lane