Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gyQdo-0007dN-F7 for pgsql-performance@arkaria.postgresql.org; Tue, 26 Feb 2019 00:30:36 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gyQdk-00056Z-Pl for pgsql-performance@arkaria.postgresql.org; Tue, 26 Feb 2019 00:30:32 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gyQdk-00056O-9X for pgsql-performance@lists.postgresql.org; Tue, 26 Feb 2019 00:30:32 +0000 Received: from mout.perfora.net ([74.208.4.194]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gyQdh-0004MG-3u for pgsql-performance@postgresql.org; Tue, 26 Feb 2019 00:30:31 +0000 Received: from [192.168.1.101] ([98.169.208.73]) by mrelay.perfora.net (mreueus001 [74.208.5.2]) with ESMTPSA (Nemesis) id 0McFxR-1ggdCd2shL-00JZxC; Tue, 26 Feb 2019 01:30:20 +0100 Message-ID: <5C74889A.3050007@sqlexec.com> Date: Mon, 25 Feb 2019 19:30:18 -0500 From: MichaelDBA User-Agent: Postbox 5.0.25 (Windows/20180328) MIME-Version: 1.0 To: Justin Pryzby CC: support@mekong.be, pgsql-performance@postgresql.org Subject: Re: Query slow for new participants References: <1551091278468-0.post@n3.nabble.com> <20190225161607.GQ28750@telsasoft.com> <20190225235919.GR28750@telsasoft.com> In-Reply-To: <20190225235919.GR28750@telsasoft.com> Content-Type: multipart/alternative; boundary="------------000606050100040805050208" X-Provags-ID: V03:K1:giRApvVLdCgGQzzUaWFoeFoBu1ZHoN0yydhBjuH32RFbYRufeiT hp2Aiasu+z6k2yz1GkPx1vW7LJ85B9dlMbalYs+wBTNesL9aZVyWQPUlbFXFHr/4QWHWC3K wgMOIpTm3ewe1Dt1V9C4o/GOga8WwBTieLZVagTeyBv4+0WxZN3yDTB93dxHolDuvsxf4wO P+nn7AvF37GQ1jO1uKTyA== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:RZawcj/TDTc=:08U+a15P8K2dQp9w7i5WJQ kjmPWKhckwX7TWPuOdQBIiVaSB/zHrDcD9kP0HqhGgRJq1czlZFx48hLdC0vvS+3J9KjfGWff 6Gfk5AafszuJ+mAKpRyFNVosCOVkd8DdwuTnFCq+CRj5meCxo9nHaQbgInyh7lG87XiiAoECM DqZ05Q0IZkzVn2/cG6POnu6kEYKjlAwxu9GJGNZ8wpBzqdQV2MGd751oE2pTGeDK232XJtcB/ cxZUsUmdyVbLsW14wGNENkqhuain0/sd05h5h60krw2kkOp7Df0Dkf8ODcO7h6/Soe3ULnjQG 9gYfqzrlouySobqgBC+Vu6zqLw6YEAB2ZDqoQlOpxf1/3F/NXxypMzTW+6t5p3FNeKR6SpeR2 rph6VVQC8Z8IxoAIxZlm2EsdkJZK0wt74IHILJIszikd5B0jPjfuKNmmcfut3GUStTQfDoqt9 6b6TAADlxmQ2219p92rzYjGf+VPeq6Vt1rWJPENAq1a9XY5uMYZjIT6u1OunhOn0bFTBaD14L 0JWP3I0QgsIc7bFqrQdOQvQTywagt/f8pIwZE+Bu81ooViNnmjkFlRyk9snrBW+MO3Nqgb7Rg J7EO1OQu7wlJOimDmnlqw+483DzgGrjnXYXApChl81X4s/rgrTp88HHo6hskhORcTYaHvmorO JvvKunu+GBBwjPDKqfxkquIZK6bjTI7CSVadTXxIiKxxIcgbxzF163qMJdRBOvLinhjJX8ldi rX7cOpVT68kIwDF9XKh4QoL1C4UjE36QlVK9u63XPMGIfyWeDJkQH6ESkqg= List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk This is a multi-part message in MIME format. --------------000606050100040805050208 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Regarding shared_buffers, please install the pg_buffercache extension and run the recommended queries with that extension during high load times to really get an idea about the right value for shared_buffers. Let's take the guess work out of it. Regards, Michael Vitale > Justin Pryzby > Monday, February 25, 2019 6:59 PM > On Tue, Feb 26, 2019 at 12:22:39AM +0100, support@mekong.be wrote: > >> Hardware >> Standard DS15 v2 (20 vcpus, 140 GB memory) > >> "effective_cache_size" "105GB" "configuration file" >> "effective_io_concurrency" "200" "configuration file" >> "maintenance_work_mem" "2GB" "configuration file" >> "max_parallel_workers" "20" "configuration file" >> "max_parallel_workers_per_gather" "10" "configuration file" >> "max_worker_processes" "20" "configuration file" >> "random_page_cost" "1.1" "configuration file" >> "shared_buffers" "35GB" "configuration file" >> "work_mem" "18350kB" "configuration file" > > I don't know for sure, but 35GB is very possibly too large shared_buffers. The > rule of thumb is "start at 25% of RAM" but I think anything over 10-15GB is > frequently too large, unless you can keep the whole DB in RAM (can you?) > >> Table Metadata >> relname, relpages, reltuples, relallvisible, relkind, relnatts, relhassubclass, reloptions, pg_table_size(oid) >> "companyarticledb" 6191886 "5.40276e+08" 6188459 "r" 44 false "50737979392" > > work_mem could probably benefit from being larger (just be careful that you > don't end up with 20x parallel workers running complex plans each node of which > using 100MB work_mem). > >> Full Table and Index Schema >> The difference is very bad for the new company, even on the simplest query >> >> SELECT * FROM CompanyArticleDB >> WHERE CompanyId = '77' >> AND ArticleId= '7869071' > > It sounds to me like the planner thinks that the distribution of companyID and > articleID are independent, when they're not. For example it think that > companyID=33 filters out 99% of the rows. > >> companyid | integer | | not null | >> articleid | integer | | not null | > >> EXPLAIN (ANALYZE, BUFFERS), not just EXPLAIN >> SELECT * FROM CompanyArticleDB >> WHERE CompanyId = '77' >> AND ArticleId= '7869071' >> "Index Scan using ix_companyarticledb_company on companyarticledb (cost=0.57..2.80 rows=1 width=193) (actual time=1011.335..1011.454 rows=1 loops=1)" >> " Index Cond: (companyid = 77)" >> " Filter: (articleid = 7869071)" >> " Rows Removed by Filter: 2674361" >> " Buffers: shared hit=30287" > >> Example for another participant, there another index is used. >> "Index Scan using pk_pricedb on companyarticledb (cost=0.57..2.79 rows=1 width=193) (actual time=0.038..0.039 rows=0 loops=1)" >> " Index Cond: ((companyid = 39) AND (articleid = 7869071))" >> " Buffers: shared hit=4" > >> I do not know why this participant is different than the others except that >> it was recently added. > > Were the tables ANALYZEd since then ? You could check: > SELECT * FROM pg_stat_user_tables WHERE relname='companyarticledb'; > > If you have small number of companyIDs (~100), then the table statistics may > incldue a most-common-values list, and companies not in the MCV list may end up > with different query plans, even without correlation issues. > > It looks like the NEW company has ~3e6 articles, out of a total ~5e8 articles. > The planner may think that companyID doesn't exist at all, so scanning the idx > on companyID will be slightly faster than using the larger, composite index on > companyID,articleID. > > Justin > >> Indexes: >> "pk_pricedb" PRIMARY KEY, btree (companyid, articleid) >> "EnabledIndex" btree (enabled) >> "ix_companyarticledb_article" btree (articleid) >> "ix_companyarticledb_company" btree (companyid) >> "participantarticlecodeindex" btree (articlecode) >> "participantdescriptionindex" gin (participantdescription gin_trgm_ops) >> Foreign-key constraints: >> "fk_companyarticledb_accountsdb" FOREIGN KEY (modifiedby) REFERENCES accountsdb(id) >> "fk_companyarticledb_accountsdb1" FOREIGN KEY (createdby) REFERENCES accountsdb(id) >> "fk_companyarticledb_accountsdb2" FOREIGN KEY (preventioncounselorid) REFERENCES accountsdb(id) >> "fk_companyarticledb_articledb" FOREIGN KEY (articleid) REFERENCES articledb(id) >> "fk_companyarticledb_companydb" FOREIGN KEY (companyid) REFERENCES companydb(id) >> "fk_companyarticledb_interfaceaccountdb" FOREIGN KEY (interfaceaccountid) REFERENCES interfaceaccountdb(id) >> "fk_companyarticledb_supplieraccountdb" FOREIGN KEY (createdbysupplier) REFERENCES supplieraccountdb(id) >> "fk_companyarticledb_supplieraccountdb1" FOREIGN KEY (modifiedbysupplier) REFERENCES supplieraccountdb(id) > --------------000606050100040805050208 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Regarding shared_buffers, please install the pg_buffercache extension and run the recommended queries with that extension during high load times to really get an idea about the right value for shared_buffers.  Let's take the guess work out of it.

Regards,
Michael Vitale

Monday, February 25, 2019 6:59 PM
On Tue, Feb 26, 2019 at 12:22:39AM +0100, support@mekong.be wrote:

Hardware
Standard DS15 v2 (20 vcpus, 140 GB memory)

"effective_cache_size" "105GB" "configuration file"
"effective_io_concurrency" "200" "configuration file"
"maintenance_work_mem" "2GB" "configuration file"
"max_parallel_workers" "20" "configuration file"
"max_parallel_workers_per_gather" "10" "configuration file"
"max_worker_processes" "20" "configuration file"
"random_page_cost" "1.1" "configuration file"
"shared_buffers" "35GB" "configuration file"
"work_mem" "18350kB" "configuration file"

I don't know for sure, but 35GB is very possibly too large shared_buffers.  The
rule of thumb is "start at 25% of RAM" but I think anything over 10-15GB is
frequently too large, unless you can keep the whole DB in RAM (can you?)

Table Metadata
relname, relpages, reltuples, relallvisible, relkind, relnatts, relhassubclass, reloptions, pg_table_size(oid)
"companyarticledb" 6191886 "5.40276e+08" 6188459 "r" 44 false "50737979392"

work_mem could probably benefit from being larger (just be careful that you
don't end up with 20x parallel workers running complex plans each node of which
using 100MB work_mem).

Full Table and Index Schema
The difference is very bad for the new company,  even on the simplest query

   SELECT * FROM CompanyArticleDB
     WHERE CompanyId = '77'
     AND ArticleId= '7869071'

It sounds to me like the planner thinks that the distribution of companyID and
articleID are independent, when they're not.  For example it think that
companyID=33 filters out 99% of the rows.

 companyid                  | integer                     |           | not null |
 articleid                  | integer                     |           | not null |

EXPLAIN (ANALYZE, BUFFERS), not just EXPLAIN
  SELECT * FROM CompanyArticleDB
    WHERE CompanyId = '77'
    AND ArticleId= '7869071'
"Index Scan using ix_companyarticledb_company on companyarticledb (cost=0.57..2.80 rows=1 width=193) (actual time=1011.335..1011.454 rows=1 loops=1)"
"  Index Cond: (companyid = 77)"
"  Filter: (articleid = 7869071)"
"  Rows Removed by Filter: 2674361"
"  Buffers: shared hit=30287"

Example for another participant, there another index is used.
"Index Scan using pk_pricedb on companyarticledb  (cost=0.57..2.79 rows=1 width=193) (actual time=0.038..0.039 rows=0 loops=1)"
"  Index Cond: ((companyid = 39) AND (articleid = 7869071))"
"  Buffers: shared hit=4"

I do not know why this participant is different than the others except that
it was recently added.

Were the tables ANALYZEd since then ?  You could check:
SELECT * FROM pg_stat_user_tables WHERE relname='companyarticledb';

If you have small number of companyIDs (~100), then the table statistics may
incldue a most-common-values list, and companies not in the MCV list may end up
with different query plans, even without correlation issues.

It looks like the NEW company has ~3e6 articles, out of a total ~5e8 articles.
The planner may think that companyID doesn't exist at all, so scanning the idx
on companyID will be slightly faster than using the larger, composite index on
companyID,articleID.

Justin

Indexes:
    "pk_pricedb" PRIMARY KEY, btree (companyid, articleid)
    "EnabledIndex" btree (enabled)
    "ix_companyarticledb_article" btree (articleid)
    "ix_companyarticledb_company" btree (companyid)
    "participantarticlecodeindex" btree (articlecode)
    "participantdescriptionindex" gin (participantdescription gin_trgm_ops)
Foreign-key constraints:
    "fk_companyarticledb_accountsdb" FOREIGN KEY (modifiedby) REFERENCES accountsdb(id)
    "fk_companyarticledb_accountsdb1" FOREIGN KEY (createdby) REFERENCES accountsdb(id)
    "fk_companyarticledb_accountsdb2" FOREIGN KEY (preventioncounselorid) REFERENCES accountsdb(id)
    "fk_companyarticledb_articledb" FOREIGN KEY (articleid) REFERENCES articledb(id)
    "fk_companyarticledb_companydb" FOREIGN KEY (companyid) REFERENCES companydb(id)
    "fk_companyarticledb_interfaceaccountdb" FOREIGN KEY (interfaceaccountid) REFERENCES interfaceaccountdb(id)
    "fk_companyarticledb_supplieraccountdb" FOREIGN KEY (createdbysupplier) REFERENCES supplieraccountdb(id)
    "fk_companyarticledb_supplieraccountdb1" FOREIGN KEY (modifiedbysupplier) REFERENCES supplieraccountdb(id)


--------------000606050100040805050208--