Received: from makus.postgresql.org (makus.postgresql.org [98.129.198.125]) by mail.postgresql.org (Postfix) with ESMTP id 7FD2E1FEAA7F for ; Wed, 11 Jul 2012 22:26:33 -0300 (ADT) Received: from mail-pb0-f46.google.com ([209.85.160.46]) by makus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1Sp8Aq-0000kb-K4 for pgsql-performance@postgresql.org; Thu, 12 Jul 2012 01:26:33 +0000 Received: by pbbrp8 with SMTP id rp8so2867178pbb.19 for ; Wed, 11 Jul 2012 18:26:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding :x-gm-message-state; bh=4GCAgb8SDliCWO3IWNyr1qlYH82tNLelbhToNmRQ0lU=; b=XW+q1T3iqEQUj0T4ZJk/IhF3RhtHDGUMF7tD2U3mFzCp91OW3OYxP6CR3gfGNs3Qz9 EP+pLhlE+/UWoLxiZgVtWfq2PsmXf+RSSJVbGiTNIUji1Ugc1BfFlimpJn3l2vqTlZ7X R8z+fK5btyMGXKoUhlsxgHEFxXmQoIdn8TJMSSgF/V0bQSW8q0jQ2FKor8NFzOWxiT14 hcFZiv3U30A5r3J5XWswzksyDd1Zah06LkqzN2nAUEfnMedQbIjbOZMFAEA6Bs/QBtE7 plAWI5ujcdoQ1Rtx6WmeAttaIOc8UMJicU1YRPVZFjjk7LUUhIAK27gxQsnXXxoWUuYb 75/A== Received: by 10.68.224.70 with SMTP id ra6mr1007576pbc.11.1342056379804; Wed, 11 Jul 2012 18:26:19 -0700 (PDT) Received: from ayaki.localdomain (office1.postnewspapers.com.au. [150.101.171.128]) by mx.google.com with ESMTPS id of4sm2742203pbb.51.2012.07.11.18.26.17 (version=SSLv3 cipher=OTHER); Wed, 11 Jul 2012 18:26:19 -0700 (PDT) Message-ID: <4FFE27B6.7000500@ringerc.id.au> Date: Thu, 12 Jul 2012 09:26:14 +0800 From: Craig Ringer User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:13.0) Gecko/20120605 Thunderbird/13.0 MIME-Version: 1.0 To: Daniel Farina CC: "pgsql-performance@postgresql.org" Subject: Re: DELETE vs TRUNCATE explanation References: <4FFCCAC4.4030503@ringerc.id.au> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Gm-Message-State: ALoCoQlUzUlIVezXxMkXofKNXFO4IEmqL9UaZgeQ6Cw1AZ/ai912HuXefsmHHoLWkmMmwHAe+nTn X-Pg-Spam-Score: -1.9 (-) X-Archive-Number: 201207/147 X-Sequence-Number: 47328 On 07/11/2012 01:22 PM, Daniel Farina wrote: > On Tue, Jul 10, 2012 at 5:37 PM, Craig Ringer wrote: >> Hi >> >> After seeing a few discussions here and on Stack Overflow I've put together >> a quick explanation of why "DELETE FROM table;" may be faster than "TRUNCATE >> table" for people doing unit testing on lots of tiny tables, people who're >> doing this so often they care how long it takes. >> >> I'd love it if a few folks who know the guts were to take a look and verify >> its correctness: > I haven't said this before, but think it every time someone asks me > about this, so I'll say it now: > > This is a papercut that should be solved with improved mechanics. > TRUNCATE should simply be very nearly the fastest way to remove data > from a table while retaining its type information, and if that means > doing DELETE without triggers when the table is small, then it should. > The only person who could thwart me is someone who badly wants their > 128K table to be exactly 8 or 0K, which seems unlikely given the 5MB > of catalog anyway. > > Does that sound reasonable? As in, would anyone object if TRUNCATE > learned this behavior? Yep, I'd object. It's more complicated and less predictable. Also, as I strongly and repeatedly highlighted in my post, DELETE FROM table; does a different job to TRUNCATE. You'd at minimum need the effect of DELETE followed by a VACUUM on the table and its indexes to be acceptable and avoid the risk of rapid table + index bloat - and that'd be lots slower than a TRUNCATE. You could be clever and lock the table then DELETE and set xmax at the same time I guess, but I suspect that'd be a bit of work and still wouldn't take care of the indexes. It's also too complicated, not least because AFAIK util commands and CRUD commands go through very different paths in PostgreSQL. I guess you could propose and post a prototype patch for a new command that tried to empty the table via whatever method it thought would be fastest. Such a new command wouldn't be bound by the accepted and expected rules followed by TRUNCATE so it could vary its behaviour based on the table, doing a real truncate on big tables and a delete-then-vaccum on small tables. I suspect you'd land up writing the fairly complicated code for the potentially multi-table delete-and-vaccum yourself. Honestly, though, it might be much better to start with "how can TRUNCATE of empty or near-empty tables be made faster?" and start examining where the time goes. -- Craig Ringer