Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eMjsP-0002ig-Gm for pgsql-performance@arkaria.postgresql.org; Thu, 07 Dec 2017 00:17:21 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eMjsO-0000Mc-L0 for pgsql-performance@arkaria.postgresql.org; Thu, 07 Dec 2017 00:17:20 +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.84_2) (envelope-from ) id 1eMjsO-0000MT-90 for pgsql-performance@lists.postgresql.org; Thu, 07 Dec 2017 00:17:20 +0000 Received: from mail-lf0-x242.google.com ([2a00:1450:4010:c07::242]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1eMjsL-0003oM-Gn for pgsql-performance@lists.postgresql.org; Thu, 07 Dec 2017 00:17:19 +0000 Received: by mail-lf0-x242.google.com with SMTP id j124so6239653lfg.2 for ; Wed, 06 Dec 2017 16:17:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:references:message-id:date:user-agent :mime-version:in-reply-to:content-transfer-encoding:content-language; bh=id0CoTQRZ+Q5naz+/Hf+l0HmBVm0QGJ66OLSd/PgLRs=; b=lC3HlnsMlv2p91F8knx5wPZuwe6mefpPeqPTPBf/VLd/MOcDqVBdzHxsvnBdq+EedU kRvtf2mnebwgrT8ReJb//goTi+qGwowXdCtGE1wrXCT64OOS0nw9X3HNGr4lQvZApAoG cBVH3ycNNhkQJe4NqGmj54SOboATGITchzYJ3QSBagx/RXcKK7TLw3+s1H/8dCj7G789 8azSf3zvARe4zzqubrnq3TSAqSHY4pOWHwbhyZwLSs8hjzCEd/YWpfuWE8D4h8j2386f P/o+JTV/C2tqjlcm7pP27A7vWKPJqFaymJRq8bfsLgaX5UxBR7ArAnSgxsEERzAauJCD YaZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:references:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=id0CoTQRZ+Q5naz+/Hf+l0HmBVm0QGJ66OLSd/PgLRs=; b=jAX+o9mdZs2YZmVl4EUnr+95Qbba7Lm3JbWA86OynP2ei0UZJc6mhQqzTWlwTQi2RV 85sl7qslek+78pDkzWxlY0mH48bNE2P5WclDYapOjO+z95VmLIYwOFt7srHY+qT30s4z dfT2vwB8w1nCrf/U/Tnlw9CuS371SY3UpNf678poFA2jjajWo3/Xn6/s/0OGFM8aIdyq BmxtTmW4L1wu/5YHycFRJX6/lJdqdqegJact9ZKTcfvB0XN+c5fMAl8d9KjL6BTGxITw g8a/MczpMWErlhWNgnRi83EY8OxMfhXxEx+tQH2+sf/jl+rK+Xhm5bjhfJu022NXRtay +A/A== X-Gm-Message-State: AJaThX4w1h4utXIEX3lGKfgKnwPqw/E4oPX06WTikcI94LuYBFgAK0xS NlTyeiEqA38XYgGKIen3/QUHQAvq X-Google-Smtp-Source: AGs4zMadNigMfN7YWgWlzGRCBoIXiRcmcta4Fpl9I0bcGqEX/1ffexfjvTJjFgxHZErSWpjWVV8fOg== X-Received: by 10.25.18.166 with SMTP id 38mr12555333lfs.166.1512605835002; Wed, 06 Dec 2017 16:17:15 -0800 (PST) Received: from [192.168.1.151] ([178.54.41.83]) by smtp.gmail.com with ESMTPSA id f67sm748393lfb.20.2017.12.06.16.17.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Dec 2017 16:17:14 -0800 (PST) Subject: Re: Bitmap scan is undercosted? From: Vitaliy Garnashevich To: Jeff Janes , Tom Lane Cc: Justin Pryzby , pgsql-performance@lists.postgresql.org References: <73a4936d-2814-dc08-ed0c-978f76f435b0@gmail.com> <20171201183427.GK18413@telsasoft.com> <20171201231104.GN18413@telsasoft.com> <18188.1512258290@sss.pgh.pa.us> <0a0bfd5f-06cc-918b-da75-4e45c4e8ea27@gmail.com> Message-ID: Date: Thu, 7 Dec 2017 02:17:13 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.5.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk > What seems odd to me is that in different kinds of tests (with > different frequency of column values): > > i1 Rows Removed by Filter = 900156, 179792, 89762 (decreased a lot) > i1 buffers = 46983, 44373, 39928 (decreased, but not a lot) > i1 best case time = 756.045, 127.814, 79.492 (decreased a lot, as well > as probably average case too) > i1 cost estimates = 67358.15, 48809.34, 46544.80 (did not decrease a lot) > > i2 Rows Removed by Filter = 900835, 980350, 991389 > i2 buffers = 46985, 46985, 46987 > i2 best case time = 377.554, 346.481, 387.874 > i2 cost estimates = 39166.34, 39247.83, 40167.34 > > It's odd that increase in actual execution time for "i1" was not > reflected enough in cost estimates. The cost even didn't go below "i2" > costs. I've added some logging, in order to get the actual numbers which were used for estimation. --drop table if exists aaa; --create table aaa as select floor(random()*100)::int num, (random()*10 < 1)::int flag from generate_series(1, 10000000) id; --analyze aaa; --set enable_bitmapscan = off; set enable_indexscan = on;  set enable_seqscan = off; --set seq_page_cost = 1.0; set random_page_cost = 1.0; set cpu_tuple_cost = 0.01; set cpu_index_tuple_cost = 0.005; set cpu_operator_cost = 0.0025; --create index i1 on aaa  (num); --drop index if exists i2; --explain (analyze,verbose,costs,buffers) select * from aaa where num = 1 and flag = 1; Index Scan using i1 on public.aaa  (cost=0.43..46697.59 rows=10641 width=8) (actual time=0.047..153.521 rows=9826 loops=1)   Rows Removed by Filter: 89948 --drop index if exists i1; --create index i2 on aaa  (flag); --explain (analyze,verbose,costs,buffers) select * from aaa where num = 1 and flag = 1; Index Scan using i2 on public.aaa  (cost=0.43..39583.11 rows=10641 width=8) (actual time=0.098..351.454 rows=9826 loops=1)   Rows Removed by Filter: 990249 LOG:  cost_index:         seq_page_cost=1.00, random_page_cost=1.00, cpu_tuple_cost=0.0100, cpu_index_tuple_cost=0.0050, cpu_operator_cost=0.0025, effective_cache_size=131072         indexStartupCost=0.43, indexTotalCost=1103.94, indexSelectivity=0.01076667, indexCorrelation=0.00208220         baserel->tuples=10000033.00, baserel->pages=44248.00, baserel->allvisfrac=0.00000000         tuples_fetched=107667.00, pages_fetched=477.00         max_IO_cost=44248.0000, min_IO_cost=477.0000, csquared=0.0000         qpqual_cost.startup=0.0000, qpqual_cost.per_tuple=0.0025, cpu_per_tuple=0.0125         spc_seq_page_cost=1.00, spc_random_page_cost=1.00         startup_cost=0.43, total_cost=46697.59 LOG:  cost_index:         seq_page_cost=1.00, random_page_cost=1.00, cpu_tuple_cost=0.0100, cpu_index_tuple_cost=0.0050, cpu_operator_cost=0.0025, effective_cache_size=131072         indexStartupCost=0.43, indexTotalCost=10123.93, indexSelectivity=0.09883333, indexCorrelation=0.82505685         baserel->tuples=10000000.00, baserel->pages=44248.00, baserel->allvisfrac=0.00000000         tuples_fetched=988333.00, pages_fetched=4374.00         max_IO_cost=44248.0000, min_IO_cost=4374.0000, csquared=0.6807         qpqual_cost.startup=0.0000, qpqual_cost.per_tuple=0.0025, cpu_per_tuple=0.0125         spc_seq_page_cost=1.00, spc_random_page_cost=1.00         startup_cost=0.43, total_cost=39583.11 Here is a break down of the total_cost into components, for i1 query and for i2 query (some rounding was removed from the formula for brevity): path->path.total_cost =   (indexTotalCost + qpqual_cost.startup) +   (max_IO_cost + csquared * (min_IO_cost - max_IO_cost)) +   (cpu_tuple_cost + qpqual_cost.per_tuple) * (indexSelectivity * baserel->tuples); path->path.total_cost =   1103.94 + 0.0000 +                                // 1103.94 +   44248.0000 + 0.0000 * (477.0000 - 44248.0000) +   // 44248.00 +   (0.0100 + 0.0025) * (0.01076667 * 10000033.00)    // 1345.84   = 46697.78;                                       // = 46697.78; path->path.total_cost =   (indexTotalCost + qpqual_cost.startup) +   (max_IO_cost + csquared * (min_IO_cost - max_IO_cost)) +   (cpu_tuple_cost + qpqual_cost.per_tuple) * (indexSelectivity * baserel->tuples); path->path.total_cost =   10123.93 + 0.0000 +                               // 10123.93 +   44248.0000 + 0.6807 * (4374.0000 - 44248.0000) +  // 17105.77 +   (0.0100 + 0.0025) * (0.09883333 * 10000000.00)    // 12354.17   = 39583.86;                                       // = 39583.86; PS. The code used for logging: /postgresql-9.3.1/src/backend/optimizer/path/costsize.c : cost_index()     ereport(LOG,             (errmsg("cost_index: \n"                     "seq_page_cost=%.2f, random_page_cost=%.2f, cpu_tuple_cost=%.4f, cpu_index_tuple_cost=%.4f, cpu_operator_cost=%.4f, effective_cache_size=%.0f\n"                     "indexStartupCost=%.2f, indexTotalCost=%.2f, indexSelectivity=%.8f, indexCorrelation=%.8f\n"                     "baserel->tuples=%.2f, baserel->pages=%.2f, baserel->allvisfrac=%.8f\n"                     "tuples_fetched=%.2f, pages_fetched=%.2f\n"                     "max_IO_cost=%.4f, min_IO_cost=%.4f, csquared=%.4f\n"                     "qpqual_cost.startup=%.4f, qpqual_cost.per_tuple=%.4f, cpu_per_tuple=%.4f\n"                     "spc_seq_page_cost=%.2f, spc_random_page_cost=%.2f\n"                     "startup_cost=%.2f, total_cost=%.2f\n",                     seq_page_cost, random_page_cost, cpu_tuple_cost, cpu_index_tuple_cost, cpu_operator_cost, (double)effective_cache_size,                     indexStartupCost, indexTotalCost, indexSelectivity, indexCorrelation,                     baserel->tuples, (double) baserel->pages, baserel->allvisfrac,                     tuples_fetched, pages_fetched,                     max_IO_cost, min_IO_cost, csquared,                     qpqual_cost.startup, qpqual_cost.per_tuple, cpu_per_tuple,                     spc_seq_page_cost, spc_random_page_cost,                     startup_cost, startup_cost + run_cost                     ))); Regards, Vitaliy