Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1csqRo-0004ar-Q8 for pgsql-performance@arkaria.postgresql.org; Tue, 28 Mar 2017 12:42:04 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1csqRo-0008IK-0M for pgsql-performance@arkaria.postgresql.org; Tue, 28 Mar 2017 12:42:04 +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 1csqRn-0008DC-0y for pgsql-performance@postgresql.org; Tue, 28 Mar 2017 12:42:03 +0000 Received: from outgoing15.cpt4.host-h.net ([197.189.249.72]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1csqRi-0006Ln-6w for pgsql-performance@postgresql.org; Tue, 28 Mar 2017 12:42:00 +0000 Received: from www20.cpt1.host-h.net ([197.221.2.20]) by antispam4-cpt4.host-h.net with esmtpsa (TLSv1.2:AES128-SHA:128) (Exim 4.86) (envelope-from ) id 1csqRZ-0006BR-7w for pgsql-performance@postgresql.org; Tue, 28 Mar 2017 14:41:52 +0200 Received: from 196-210-206-12.dynamic.isadsl.co.za ([196.210.206.12] helo=DMZHOST) by www20.cpt1.host-h.net with esmtpa (Exim 4.80) (envelope-from ) id 1csqRY-0000hW-7p for pgsql-performance@postgresql.org; Tue, 28 Mar 2017 14:41:48 +0200 Received: from [10.0.0.41] (Unknown [10.0.0.41]) by DMZHOST with ESMTPA ; Tue, 28 Mar 2017 14:41:39 +0200 Subject: Re: Best design for performance To: pgsql-performance@postgresql.org References: <04c401d2a753$f4b78e00$de26aa00$@exa.co.za> <052b01d2a761$06e8c4b0$14ba4e10$@exa.co.za> From: Riaan Stander Message-ID: <113e6bde-6595-44b8-79a4-992a2eea4c27@exa.co.za> Date: Tue, 28 Mar 2017 14:41:37 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/alternative; boundary="------------EBCBE4E0D33C959D71C3C4DA" X-Authenticated-Sender: smtprelay@exa.co.za X-Virus-Scanned: Clear (ClamAV 0.99.2/23244/Tue Mar 28 06:33:34 2017) X-Originating-IP: 197.221.2.20 X-SpamExperts-Domain: exa.co.za X-SpamExperts-Username: Authentication-Results: host-h.net; auth=pass (login) smtp.auth=@exa.co.za X-SpamExperts-Outgoing-Class: ham X-SpamExperts-Outgoing-Evidence: Combined (0.17) X-Recommended-Action: accept X-Filter-ID: s0sct1PQhAABKnZB5plbIWL5vMUYxb2kq1uspbfEA9+ihNzEqHRR3fXVWQ7SEawUiwQzKw+6v3Ca IMG6s7LqJJlV3j2ipgsAbbE1JvuwkkgZ4m00l3uPRdWwNfw+Po+GO76XSTAwtV4mg4i2ouCDa4AU hvIWAV5xUW/+gAh4vXopLTNS7p6wUzLIF5CToH5URcOb18WfxGyg6Om6u4YYmzW5zsAuto4ysjOF RB9pBBOMytmwoSOAsUiZHL4elTOeW/T3iEdLQrEzANTH1RO+ZuWBOXp8nHKe0R+FkIqN7hlBaLCK i/3d82ndyQckqlk5z3irZHx8XwBM/aZ+josQAfUf9oDBqtClgM5jH/om1Q4tH6VyaEKKyFb3KuYS PtYeOngwKsK/v8O00LnH1NcGs0PkGda5olUXOJzJbtkypWIEPaEM6Ls9T603i0+693PcSG91B+fq BSqO/3ggQ6bm4zYYB0K6DpInazve5ezQP+U2yPRk3H1E4ANRdN1BlPI5rJaWDcne6cToXniqtJYh 2fh2wfAJPI99az2gqFCIIfZ1+KzU7SnoXsKZpOw3kjuyUE5+n83VHgUVFZ+GUeLTXJaGzcj+Mc5i sodBI9N2YC5aCjuBDzdB/sn9JnExigkZNff1J0V4Egf9XlsVRD9nnuidX4Ts4xdG+C13IyWeZaJ1 h9G8J4XxQMjZy2EIZOo7Ok+wpVgQQ4AiySdYEKpijx2QUKDpYYAa9eqMguKDIPW5X3u97YLfFuPW aicDtNrQuCQdZLNhLwRrtF5z+7s1/t/VIeLbUrGXPGnBDeG6QE4Z65tSUaCtARdCSMvuUPrCdRPo XeQjpnGJFvzCF+fyxK6y/983ZobKoSO5qw+kw4o= X-Report-Abuse-To: spam@antispammaster.host-h.net X-Pg-Spam-Score: -2.6 (--) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-performance Precedence: bulk Sender: pgsql-performance-owner@postgresql.org This is a multi-part message in MIME format. --------------EBCBE4E0D33C959D71C3C4DA Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit On 28 Mar 2017 4:22 AM, Claudio Freire wrote: >> From: Claudio Freire [mailto:klaussfreire@gmail.com] >> >> How did you query the table's size? You're probably failing to account for TOAST tables. >> >> I'd suggest using pg_total_relation_size. > ... > On Mon, Mar 27, 2017 at 10:17 PM, Riaan Stander wrote: >> I'm using the first query from here. >> https://wiki.postgresql.org/wiki/Disk_Usage > Please don't top post. > > It's a surprisingly big difference. TOAST could be compressing the > array, but I wouldn't expect it to be that compressible. Do you have > any stats about the length of the site array per row? > >> The plan is to do the rights checking in the application. The join solution gets used for reports to filter data & client adhoc queries. > Especially for reporting queries, you want the planner's stats to be > as accurate as possible, and placing a literal sites arrays in the > query in my experience is the best way to achieve that. But that is > indeed limited to reasonably small arrays, thereby the need to have > both variants to adapt the query to each case. > > If you can't afford to do that change at the application level, I > would expect that the original schema without the array should be > superior. The array hides useful information from the planner, and > that *should* hurt you. > > You'll have to test with a reasonably large data set, resembling a > production data set as much as possible. > > I did some more testing on this. My primary concern that not all the data was there in the array version,but after doing some extensive testing all seems to be there. I've done some comparisons vs the SQL Server version too. SQL Sever Table with over 700mil records: CREATE TABLE [dbo].[usrUserRights] ( [UserId] [dbo].[dm_Id] NOT NULL, [SiteId] [dbo].[dm_Id] NOT NULL, [RightId] [dbo].[dm_Id] NOT NULL, CONSTRAINT [pk_usrUserRights_UserId_RightId_SiteId] PRIMARY KEY CLUSTERED([UserId],[RightId],[SiteId]) ); Takes23GB for data and 200MB for indexes. Postgres table with over 700mil records: CREATE TABLE security.user_right_site2 ( user_id bigint NOT NULL, right_id bigint NOT NULL, site_id bigint NOT NULL ); create index on security.user_right_site2(user_id, right_id); Takes 35GB data and 26GB index, for a total of 61GB. That is quite a large increase over SQL Server storage. Am I missing something? Makes me worry about the rest of the database we still have to convert. Postgres Array version ends up with only 600k records, due to aggregation: CREATE TABLE security.user_right_site ( user_id bigint NOT NULL, right_id bigint NOT NULL, sites bigint[] ); create index on security.user_right_site(user_id, right_id); Takes 339Mb data, 25Mb index and 2240Mb TOAST Regarding the Array length for each of these. They currently have max 6500 site ids. Regards Riaan --------------EBCBE4E0D33C959D71C3C4DA Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 8bit On 28 Mar 2017 4:22 AM, Claudio Freire wrote:
From: Claudio Freire [mailto:klaussfreire@gmail.com]

How did you query the table's size? You're probably failing to account for TOAST tables.

I'd suggest using pg_total_relation_size.
...
On Mon, Mar 27, 2017 at 10:17 PM, Riaan Stander <rstander@exa.co.za> wrote:
I'm using the first query from here.
https://wiki.postgresql.org/wiki/Disk_Usage
Please don't top post.

It's a surprisingly big difference. TOAST could be compressing the
array, but I wouldn't expect it to be that compressible. Do you have
any stats about the length of the site array per row?

The plan is to do the rights checking in the application. The join solution gets used for reports to filter data & client adhoc queries.
Especially for reporting queries, you want the planner's stats to be
as accurate as possible, and placing a literal sites arrays in the
query in my experience is the best way to achieve that. But that is
indeed limited to reasonably small arrays, thereby the need to have
both variants to adapt the query to each case.

If you can't afford to do that change at the application level, I
would expect that the original schema without the array should be
superior. The array hides useful information from the planner, and
that *should* hurt you.

You'll have to test with a reasonably large data set, resembling a
production data set as much as possible.


I did some more testing on this. My primary concern that not all the data was there in the array version, but after doing some extensive testing all seems to be there.

I've done some comparisons vs the SQL Server version too.
SQL Sever Table with over 700mil records:

CREATE TABLE [dbo].[usrUserRights]  (
     [UserId]   [dbo].[dm_Id] NOT NULL,
     [SiteId]   [dbo].[dm_Id] NOT NULL,
     [RightId]  [dbo].[dm_Id] NOT NULL,
     CONSTRAINT [pk_usrUserRights_UserId_RightId_SiteId] PRIMARY KEY CLUSTERED([UserId],[RightId],[SiteId])

);

Takes
23GB for data and 200MB for indexes.

Postgres table with over 700mil records:

CREATE TABLE security.user_right_site2
(
    user_id bigint NOT NULL,
    right_id bigint NOT NULL,
    site_id bigint NOT NULL
);
create index on security.user_right_site2(user_id, right_id);

Takes 35GB data and 26GB index, for a total of 61GB.

That is quite a large increase over SQL Server storage. Am I missing something? Makes me worry about the rest of the database we still have to convert.

Postgres Array version ends up with only 600k records, due to aggregation:
CREATE TABLE security.user_right_site
(
    user_id bigint NOT NULL,
    right_id bigint NOT NULL,
    sites bigint[]
);
create index on security.user_right_site(user_id, right_id);

Takes 339Mb data, 25Mb index and 2240Mb TOAST

Regarding the Array length for each of these. They currently have max 6500 site ids.

Regards
Riaan
--------------EBCBE4E0D33C959D71C3C4DA--