Received: from malur.postgresql.org ([2a02:16a8:dc51::56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fkYYu-00049D-RX for pgsql-performance@arkaria.postgresql.org; Tue, 31 Jul 2018 17:35:57 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1fkYYt-0004vx-9n for pgsql-performance@arkaria.postgresql.org; Tue, 31 Jul 2018 17:35:55 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fkYYs-0004vq-3g for pgsql-performance@lists.postgresql.org; Tue, 31 Jul 2018 17:35:55 +0000 Received: from out1-smtp.messagingengine.com ([66.111.4.25]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fkYYo-0004PL-UC for pgsql-performance@postgresql.org; Tue, 31 Jul 2018 17:35:52 +0000 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id D954B21AF1; Tue, 31 Jul 2018 13:35:49 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Tue, 31 Jul 2018 13:35:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anarazel.de; h= cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=Ncj9RMg7rwMrW9zFlW5TDlXocBcWERF5qMdP4p2xz6c=; b=rh850whT vKzu+WEuKDxZhK6Ik2NMtc5CXunS5a73WPJAJNmlXLx4wLY7AWGSWMnwPfWMKEEk EPgexpvsVpx895uWbJlxalzfyxrrYrD2SHFkcEP+cRUsDc7O4+RXhVVNsAfEyWZw vp4yNXGk0aK+sn7zpqyX00o1JFCAUTBGkU6YO02xi5+LhHwDXE0Rkdig/GtUn/Bw 2PczlxWtGXlVgU8CO7g/q5jFNFmQTMM+ZTlLOkIsbjvtzncgSkw1QjtY5MTKJfiL GNWgge47vryw6pCONihONkZF88h807QA1w/snWyVZbTRjqOvHt1wtG3ptlTgPCh3 t5TV9xGIBcWTxw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; bh=Ncj9RMg7rwMrW9zFlW5TDlXocBcWE RF5qMdP4p2xz6c=; b=n/xaRUOj272/3ZcOWq3K2peLF9bYQVdk43ctLFOa6cRNb Flm/TzKkfr3Dzof07KWaIRWbmbBHHcHlPsiZJp5C4l04XSo4FvhYeeF9rN8iZTDT o5DyoPi2eVBsX8pU1/JoZ9J/zfDRMgMTmo/IxJhES1FVcurVgYKuXNI2sjRN7FIz qFprlqjPRq5dZSHQqJ/vf9OvBW0KFWDf743aIKIu3oQ67FTo6i0sRZYQm1ctTBUp n0keyrHBb4Q6n1TatyYkqgtImB1AQp8ViCHyPSPZLgG4OWDochsquBbu4NYhl+Cm v9jgXyb1VdguIJaczspCwo4ab+553zMKLTtknk+VQ== X-ME-Proxy: X-ME-Sender: Received: from intern.anarazel.de (c-98-210-140-171.hsd1.ca.comcast.net [98.210.140.171]) by mail.messagingengine.com (Postfix) with ESMTPA id 3F22E10284; Tue, 31 Jul 2018 13:35:49 -0400 (EDT) Date: Tue, 31 Jul 2018 10:35:48 -0700 From: Andres Freund To: Jeff Janes Cc: Pavel Stehule , Tom Lane , David Rowley , Dinesh Kumar , postgres performance list Subject: Re: Performance difference in accessing differrent columns in a Postgres Table Message-ID: <20180731173548.ryxtb6x64d7kbjdw@alap3.anarazel.de> References: <16506.1532905259@sss.pgh.pa.us> <20180730172335.zcwqyyjqgvx2pewu@alap3.anarazel.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk Hi, On 2018-07-31 12:56:26 -0400, Jeff Janes wrote: > On Mon, Jul 30, 2018 at 1:23 PM, Andres Freund wrote: > > > On 2018-07-30 07:19:07 -0400, Jeff Janes wrote: > > > > > And indeed, in my hands JIT makes it almost 3 times worse. > > > > Not in my measurement. Your example won't use JIT at all, because it's > > below the cost threshold. So I think you might just be seeing cache + > > hint bit effects? > > > > No, it is definitely JIT. The explain plans show it, and the cost of the > query is 230,000 while the default setting of jit_above_cost is 100,000. > It is fully reproducible by repeatedly toggling the JIT setting. It > doesn't seem to be the cost of compiling the code that slows it down (I'm > assuming the code is compiled once per tuple descriptor, not once per > tuple), but rather the efficiency of the compiled code. Interesting. I see a smaller benefit without opt, but still one. I guess that depends on code emission. > > > Run against ab87b8fedce3fa77ca0d6, I get 12669.619 ms for the 2nd JIT > > > execution and 4594.994 ms for the JIT=off. > > > > Even with a debug LLVM build, which greatly increases compilation > > overhead, I actually see quite the benefit when I force JIT to be used: > > > > I don't see a change when I compile without --enable-debug, > and jit_debugging_support is off, or in 11beta2 nonexistent. How can I > know if I have a debug LLVM build, and turn it off if I do? llvm-config --assertion-mode should tell you. > > postgres[26832][1]=# ;SET jit_above_cost = -1; set jit_optimize_above_cost > > = 0; set jit_inline_above_cost = 0; > > postgres[26832][1]=# explain (analyze, buffers, timing off) select pk, > > int200 from i200c200; > > > > Lowering jit_optimize_above_cost does redeem this for me. It brings it > back to being a tie with JIT=OFF. I don't see any further improvement by > lowering jit_inline_above_cost, and overall it is just a statistical tie > with JIT=off, not an improvement as you get, but at least it isn't a > substantial loss. Interesting, as posted, I do see quite measurable improvements. What's your version of LLVM? > Under what conditions would I want to do jit without doing optimizations on > it? Is there a rule of thumb that could be documented, or do we just use > the experimental method for each query? I don't think we quite know yet. Optimization for larger queries can take a while. For expression heavy queries there's a window where JITing can help, but optimization can be beneficial. > I had previously done a poor-man's JIT where I created 4 versions of the > main 'for' loop in slot_deform_tuple. I did a branch on "if(hasnulls)", > and then each branch had two loops, one for when 'slow' is false, and then > one for after 'slow' becomes true so we don't have to keep setting it true > again once it already is, in a tight loop. I didn't see noticeable > improvement there (although perhaps I would have on different hardware), so > didn't see how JIT could help with this almost-entirely-null case. I'm not > trying to address JIT in general, just as it applies to this particular > case. I don't see how it follows from that observation that JITing can't be beneficial? The bitmap access alone can be optimized if you unroll the loop (as now the offsets into it are constant). The offset computations into tts_values/isnull aren't dynamic anymore. The loop counter is gone. And nearly all tuple have hasnulls set, so specializing for that case isn't going to get you that much, it's perfectly predictable. > Unrelated to JIT and relevant to the 'select pk, int199' case but not the > 'select pk, int200' case, it seems we have gone to some length to make slot > deforming be efficient for incremental use, but then just deform in bulk > anyway up to maximum attnum used in the query, at least in this case. Is > that because incremental deforming is not cache efficient? Well, that's not *quite* how it works: We always deform up to the point used in a certain "level" of the query. E.g. if a select's where clause needs something up to attribute 3, the seqscan might deform only up to there, even though an aggregate ontop of that might need up to 10. But yes, you're right, uselessly incrementally deforming isn't cache efficient. I think before long we're going to have to change the slot mechanism so we don't deform columns we don't actually need. I.e we'll need something like a bitmap of needed columns and skip over unneeded ones. When not JITed that'll allow us to skip copying such columns (removing an 8 and 1 byte write), when JITing we can do better, and e.g. entirely skip processing fixed width NOT MULL columns that aren't needed. Greetings, Andres Freund