Thread
-
Routine analyze of single column prevents standard autoanalyze from running at all
Tomasz Ostrowski <tometzky+pg@ato.waw.pl> — 2016-06-06T14:25:29Z
Hi. I'm routinely bulk inserting data to a PostgreSQL table and then analyzing a single column of the table, because it contains data which significantly changes histogram of this column values - for example something like adding rows with "todo=true" column, when all rows before bulk insert have "todo=false". This column has rather small "statistics" value, so analyze of it is fairly fast, which is important as I'm doing it often and also in parallel (and analyze blocks - only one can run at the time). The full analyze of this large table would take a lot of time (20 times more actually), and I can't perform it after each bulk insert. But I've noticed that a standard automatic analyze, which should work in background, never runs. I've noticed that this fast analyze of one column resets pg_stat_user_tables(n_mod_since_analyze) counter. I suppose that the decision to analyze the whole table is based on these values from pg_stat_user_tables and autovacuum_analyze_threshold and autovacuum_analyze_scale_factor settings. And in this case this highly updated table never reaches these values. I suppose this is a bug - an analyze, which does not analyze all columns, should not reset pg_stat_user_tables(n_mod_since_analyze). What do you think? -- Tomasz "Tometzky" Ostrowski
-
Re: [BUGS] Routine analyze of single column prevents standard autoanalyze from running at all
Tom Lane <tgl@sss.pgh.pa.us> — 2016-06-06T18:38:00Z
[ redirecting to -hackers ] Tomasz Ostrowski <tometzky+pg@ato.waw.pl> writes: > I'm routinely bulk inserting data to a PostgreSQL table and then > analyzing a single column of the table, because it contains data which > significantly changes histogram of this column values - for example > something like adding rows with "todo=true" column, when all rows before > bulk insert have "todo=false". > But I've noticed that a standard automatic analyze, which should work in > background, never runs. I've noticed that this fast analyze of one > column resets pg_stat_user_tables(n_mod_since_analyze) counter. > I suppose this is a bug - an analyze, which does not analyze all > columns, should not reset pg_stat_user_tables(n_mod_since_analyze). What > do you think? I'm inclined to think that this is a reasonable complaint. A usage pattern like that probably hasn't come up before; but now that it has, it's clear it shouldn't block auto-analyze from happening. A cheap-and-dirty solution would be to not send a PgStat_MsgAnalyze message at all, but I think that's probably undesirable: typically it would be a good thing to accept the new n_live_tuples and n_dead_tuples estimates. What we could do instead is add a bool flag to PgStat_MsgAnalyze saying whether or not to reset changes_since_analyze. It would be safe enough to back-patch such a change, because the stats collector messages are private to the backend (in fact, really private to pgstat.c). One question here is whether there is any connection between changes_since_analyze and the tuple-count estimates that would make it improper to update the latter and not the former. I can't really see one; in fact, changes_since_analyze is pretty squishy anyway because changes made by an ANALYZE's own transaction are already accounted for in the new pg_statistic entries but will be added to changes_since_analyze at commit despite that. So I'd go ahead and update all the fields other than changes_since_analyze in this case. Another interesting consideration is that if the table's columns have different stats targets, a selective-column ANALYZE might possibly sample fewer rows than an all-columns ANALYZE would. This might mean that our new tuple-count estimates are less accurate than autoanalyze would get. So you could possibly argue that we shouldn't update the tuple-count estimates after all. But I don't particularly believe that, because it disregards the fact that the new estimates are, well, new. Even if they have more statistical risk than autoanalyze would have, they could well be better just by virtue of having seen whatever bulk updates might have happened since the last autoanalyze. So my inclination is to disregard this fine point. (Though it's interesting to ask whether Tomasz's use case includes a lower-than-default stats target for his very volatile column ...) Also, I'd be a bit inclined to disable the counter reset whenever a column list is specified, disregarding the corner case where a list is given but it includes all the table's analyzable columns. It doesn't really seem worth the effort to account for that case specially (especially after you consider that index expressions should count as analyzable columns). Thoughts? regards, tom lane
-
Re: [BUGS] Routine analyze of single column prevents standard autoanalyze from running at all
Tom Lane <tgl@sss.pgh.pa.us> — 2016-06-06T19:59:37Z
I wrote: > Tomasz Ostrowski <tometzky+pg@ato.waw.pl> writes: >> I suppose this is a bug - an analyze, which does not analyze all >> columns, should not reset pg_stat_user_tables(n_mod_since_analyze). What >> do you think? > I'm inclined to think that this is a reasonable complaint. A usage > pattern like that probably hasn't come up before; but now that it has, > it's clear it shouldn't block auto-analyze from happening. Attached is a draft patch for this, which I propose to apply and back-patch. Any objections? regards, tom lane
-
Re: [BUGS] Routine analyze of single column prevents standard autoanalyze from running at all
Josh Berkus <josh@agliodbs.com> — 2016-06-06T20:23:30Z
On 06/06/2016 01:38 PM, Tom Lane wrote: > Also, I'd be a bit inclined to disable the counter reset whenever a column > list is specified, disregarding the corner case where a list is given but > it includes all the table's analyzable columns. It doesn't really seem > worth the effort to account for that case specially (especially after > you consider that index expressions should count as analyzable columns). > > Thoughts? +1. Better to err on the side of duplicate analyzes than none at all. Also, I'm not surprised this took so long to discover; I doubt most users are aware that you *can* analyze individual columns. -- -- Josh Berkus Red Hat OSAS (any opinions are my own)
-
Re: [BUGS] Routine analyze of single column prevents standard autoanalyze from running at all
Jim Nasby <jim.nasby@bluetreble.com> — 2016-06-08T00:25:13Z
On 6/6/16 3:23 PM, Josh berkus wrote: > On 06/06/2016 01:38 PM, Tom Lane wrote: > >> Also, I'd be a bit inclined to disable the counter reset whenever a column >> list is specified, disregarding the corner case where a list is given but >> it includes all the table's analyzable columns. It doesn't really seem >> worth the effort to account for that case specially (especially after >> you consider that index expressions should count as analyzable columns). >> >> Thoughts? > > +1. Better to err on the side of duplicate analyzes than none at all. > > Also, I'm not surprised this took so long to discover; I doubt most > users are aware that you *can* analyze individual columns. Is there any significant advantage to not analyzing all columns? Only case I can think of is if you have a fair number of columns that have been toasted; otherwise I'd think IO would completely swamp any other considerations. -- Jim Nasby, Data Architect, Blue Treble Consulting, Austin TX Experts in Analytics, Data Architecture and PostgreSQL Data in Trouble? Get it in Treble! http://BlueTreble.com 855-TREBLE2 (855-873-2532) mobile: 512-569-9461
-
Re: [BUGS] Routine analyze of single column prevents standard autoanalyze from running at all
Tom Lane <tgl@sss.pgh.pa.us> — 2016-06-08T03:04:05Z
Jim Nasby <Jim.Nasby@BlueTreble.com> writes: > Is there any significant advantage to not analyzing all columns? Only > case I can think of is if you have a fair number of columns that have > been toasted; otherwise I'd think IO would completely swamp any other > considerations. Yeah, my guess is that the OP's example where analyzing just one column was significantly cheaper boiled down to some of the other columns being mostly toasted data. Otherwise it's hard to see how there's much more expense in analyzing them all. regards, tom lane
-
Re: [BUGS] Routine analyze of single column prevents standard autoanalyze from running at all
Tomasz Ostrowski <tometzky+pg@ato.waw.pl> — 2016-06-08T06:19:58Z
W dniu 2016-06-08 o 05:04, Tom Lane pisze: > Jim Nasby <Jim.Nasby@BlueTreble.com> writes: >> Is there any significant advantage to not analyzing all columns? Only >> case I can think of is if you have a fair number of columns that have >> been toasted; otherwise I'd think IO would completely swamp any other >> considerations. > > Yeah, my guess is that the OP's example where analyzing just one column > was significantly cheaper boiled down to some of the other columns being > mostly toasted data. Otherwise it's hard to see how there's much more > expense in analyzing them all. Actually no - this volatile column has smaller "statistics" than most of the table, so analyzing it is much faster when it's data is not in RAM. Here is a small exaggerated example showing a difference: $ psql tometzky=> create table test (id serial, data text); tometzky=> insert into test(data) select 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' ||generate_series(0,10000000)::text; tometzky=> alter table test alter column id set statistics 10; tometzky=> alter table test alter column data set statistics 1000; tometzky=> \q # Drop OS page cache and restart postgres # so the table data won't be in RAM anymore: $ sudo sh -c 'echo 1 >/proc/sys/vm/drop_caches' $ sudo systemctl restart postgresql; # Test single column analyze: $ psql tometzky=> \timing Timing is on. tometzky=> analyze verbose test(id); INFO: analyzing "public.test" INFO: "test": scanned 3000 of 123457 pages, containing 243000 live rows and 0 dead rows; 3000 rows in sample, 2712238 estimated total rows ANALYZE Time: 422,521 ms tometzky=> \q # Drop OS page cache and restart postgres again $ sudo sh -c 'echo 1 >/proc/sys/vm/drop_caches' $ sudo systemctl restart postgresql; $ psql tometzky=> \timing Timing is on. tometzky=> analyze verbose test; INFO: analyzing "public.test" INFO: "test": scanned 123457 of 123457 pages, containing 10000001 live rows and 0 dead rows; 300000 rows in sample, 10000001 estimated total rows ANALYZE Time: 9447,519 ms -- Tomasz "Tometzky" Ostrowski
-
Re: [BUGS] Routine analyze of single column prevents standard autoanalyze from running at all
Tom Lane <tgl@sss.pgh.pa.us> — 2016-06-08T14:04:51Z
Tomasz Ostrowski <tometzky+pg@ato.waw.pl> writes: > W dniu 2016-06-08 o 05:04, Tom Lane pisze: >> Yeah, my guess is that the OP's example where analyzing just one column >> was significantly cheaper boiled down to some of the other columns being >> mostly toasted data. Otherwise it's hard to see how there's much more >> expense in analyzing them all. > Actually no - this volatile column has smaller "statistics" than most of > the table, so analyzing it is much faster when it's data is not in RAM. Oh, so you *will* be vulnerable to the side-effect we wondered about earlier, wherein the manual ANALYZE scans fewer blocks and may therefore derive a less-accurate tuple count estimate than auto-analyze gets. It'll be interesting to see how the fix plays out for you --- please pay attention to whether the pg_stat_all_tables.n_live_tup/n_dead_tup numbers jump around in unexpected ways. regards, tom lane