Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ow1LE-0007nF-45 for pgsql-performance@arkaria.postgresql.org; Fri, 18 Nov 2022 13:23:36 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1ow1LD-0003Pg-0e for pgsql-performance@arkaria.postgresql.org; Fri, 18 Nov 2022 13:23:35 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ow1LC-0003PW-MU for pgsql-performance@lists.postgresql.org; Fri, 18 Nov 2022 13:23:34 +0000 Received: from mail-ej1-x635.google.com ([2a00:1450:4864:20::635]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1ow1LA-0006cu-3k for pgsql-performance@postgresql.org; Fri, 18 Nov 2022 13:23:34 +0000 Received: by mail-ej1-x635.google.com with SMTP id kt23so12973898ejc.7 for ; Fri, 18 Nov 2022 05:23:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; h=content-transfer-encoding:in-reply-to:from:references:to :content-language:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=QonAXftBJlDnt5MydSsPPFbYHwu8vaByijC38fr2GQI=; b=VtcmK1b3ceRtGCzXRX9qvP40xdXRKpzWZgBKwBzcrqCfbWz72XHfsdKc1+Kx2DbnlK q1Keu1C3YGydJ1iACIDGJLGX2Qj0IdmVr3OwjMP2pFXRAEevh1HIzNnAoVfovO/ocLTj ABR1en/0gHU5jBOfNGTiHMrOETUN37x7UCQsrPEWMZFRq7gD5M/A8oS2GjyucuDDRSda 1IQFIDI1JkzrpvZ41o+1QKT+aL+QZnHo8SOGhmNna0wNpK12oj5VTOTyi5uIl7gjlPUf DJI4tTuacUXf94vuLGT1SPCxH0uMG638qS11kfCLCODw1gv0/AySof7Pgxg8bNofuwWa 66Ew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:in-reply-to:from:references:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=QonAXftBJlDnt5MydSsPPFbYHwu8vaByijC38fr2GQI=; b=TM+LNC1mk5H1KlQn8tUt/8Blhml6EdEy1vyJcgP77t/38hFTQjCR7/R1iYmY7OaAhQ 969t/lQtD0+8BQkPynkNundza+Bh4ZmDFAzVKe+PfDTXuz7E3Mc3Pg8Er6eUNXuIxlE6 H81sXeRFJZDCS0Wq33PMA7+1RJ7UlzTSD6+0JjTEv6+K2cHZ2C7Td/z8qsCPwnMdDYpi Ji7DljuXo0WURxHCssy3pfyvOo2udZI0NWmS7CZ0T1hD4XYj4wmCV/6TzdvpxaI/XTAH 2CFH5ma67Iom1HZJsIVAy/8+mu4B5ogtesjYQl4BVq2M17tVkhuoWaO8ODrynchQQVU0 kuAw== X-Gm-Message-State: ANoB5pmHpDAMTbmhVfm77pH/mFc7bohAM62M5D1tsX2rkGyYyX9/K9pk ln0BURys3kBmqHwSKAh9GmprmA6eSZKgp9xN4TFc6M5/Ru1Q429ZQkqHQlnNGHb/1OyVXDuqw+D A3cIT/LzwJbzdP+NZiOqrugWHmNzytgI+zwstutw+ELJBMdyzpM8ueUyATgAHHxfMt31HnvehLv Ta7A6mbiVqG+qUOaVEA1aWGisaIVMbc6DJ1mBMJS0q8lmOMbZAIFtg0EU0z6sAwQ2n22elFyY3a UaoJH/NM0SLLg4XTt3gMQcOOteX9PY0r8WUdWktIES91GVTqG/3jrHEoQaK X-Google-Smtp-Source: AA0mqf6h5jRHvclrlG4cnwD39b+SyJK4aTUvYTNuN0Rrc69pxHAPQFdJYWup7Zpc8YPe8r8Hj22H0w== X-Received: by 2002:a17:906:edb0:b0:7a0:948d:80ae with SMTP id sa16-20020a170906edb000b007a0948d80aemr5944688ejb.658.1668777811305; Fri, 18 Nov 2022 05:23:31 -0800 (PST) Received: from [10.137.0.17] (static-84-42-175-93.bb.vodafone.cz. [84.42.175.93]) by smtp.gmail.com with ESMTPSA id lc14-20020a170906dfee00b007ae07e63a85sm1695721ejc.211.2022.11.18.05.23.30 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 18 Nov 2022 05:23:30 -0800 (PST) Message-ID: <52c1cb75-89bc-61c4-2ec9-42c683ba8f14@enterprisedb.com> Date: Fri, 18 Nov 2022 14:23:31 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.1 Subject: Re: why choosing an hash index instead of the btree version even if the cost is lower? Content-Language: en-US To: Luca Ferrari , postgres performance list References: From: Tomas Vondra In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-CLOUD-SEC-AV-Info: enterprisedb,google_mail,monitor X-CLOUD-SEC-AV-Sent: true X-Gm-Spam: 0 X-Gm-Phishy: 0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 11/18/22 13:15, Luca Ferrari wrote: > Hi all, > I'm just having a doubt about the choice of the planner for a small > example table. > I've a table with a numeric column (integer), and I've created two > indexes on such column, one btree and one hash. The hash results much > larger as the btree, but what puzzles me is that executing an equality > simple query, the system chooses the hash index (that has a final cost > of 8984.08 while the btree index would have a final cost a little > lower (8901.94). > > The only difference I can spot in the EXPLAIN plans is that the btree > index has an initial cost, but I don't think this is the reason, since > it should be the final cost what matters, right? > > Now, even if the two costs are comparable, why does the optimizer > chooses to use the larger hash index? What am I missing here and where > do I have to dig? > Using EXPLAIN ANALYZE shows that the two indexes are very similar > timings, so while using the hash index is clearly not a wrong choice, > I'm wondering why preferring a bigger index. > > Please note that the table has been manually ANALYZEd and is not clustered. > My guess is this is due to STD_FUZZ_FACTOR, see [1] and [2]. That is, when comparing costs, we require the cost to be at least 1%, because we have a cheapest path, and we're checking if it's worth building another one (which is not free - we have to allocate stuff etc.). And if the difference is tiny, it's not worth it. In this case we have the indexscan for the hash index, with cost 8971.95, and we're considering to build indexacan path for the btree index. We haven't built it yet, we only calculate cost 8891.65. But 8971.95/8891.65 = 1.009 So it's close to 1.01, but just a little bit less. So we conclude it's not worth building the second path, and we keep the hash index scan. Now, this is based on the idea that small cost difference => small runtime difference And from the timings you shared, this seems to be the case - 6.0 vs. 6.8 ms is fairly close. I'd say btree/hash estimates this close are not very common in practice, considering the costing formulas for the index types is quite different. You may try tweaking the different cost parameters (e.g. operator cost, random page cost) to make the difference larger. regards [1] https://github.com/postgres/postgres/blob/master/src/backend/optimizer/util/pathnode.c#L51 [2] https://github.com/postgres/postgres/blob/master/src/backend/optimizer/util/pathnode.c#L166 -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company