ãã® ã·ãªãŒãºã® 以åã® æçš¿ã§ã¯ ã EXPLAINåºåã®èªã¿æ¹ãšåè¡ïŒæäœ/ããŒãïŒã®æå³ã«ã€ããŠèª¬æããŸããã
æçµæçš¿ã§ã¯ãPostgresããOperation Yãã§ã¯ãªããOperation Xããéžæããçç±ã説æããŸãã
PostgreSQLã¹ã±ãžã¥ãŒã©ãçµ±èšã«åºã¥ããŠæäœãéžæãããšèããããšããããããããŸããã ã©ããªçµ±èšïŒ
å¯èœãªéãåçŽãªã·ããªãªãæ³åããŠã¿ãŸãããã
SELECT * FROM table WHERE column = some_value;
ããŒãã«å ã®ãã¹ãŠã®è¡ã«åãsome_valueå€ãããå Žåãåã«ã€ã³ããã¯ã¹ïŒæ¢åã®å¯èœæ§ãããïŒãé©çšããŠãæå³ããããŸããã
äžæ¹ãåã®å€ãäžæïŒãŸãã¯ã»ãŒäžæïŒã§ããå Žåã¯ãã€ã³ããã¯ã¹ã䜿çšããããšããå§ãããŸãã
äœãèµ·ãããèŠãŠã¿ãŸãããïŒ
create table test ( all_the_same int4, almost_unique int4 ); CREATE TABLE insert into test ( all_the_same, almost_unique ) select 123, random() * 1000000 from generate_series(1,100000); INSERT 0 100000
ãã®ããã100,000è¡ã®ããŒãã«ãããããall_the_sameãåã®å€ã¯åžžã«åãïŒ123ïŒã§ãããååã瀺ãããã«ãalmost_uniqueåã¯ã»ãŒäžæã§ãã
select count(*), count(distinct almost_unique) from test; count | count --------+------- 100000 | 95142 (1 row)
次ã«ãããããçããããããã«ã2ã€ã®åçŽãªã€ã³ããã¯ã¹ãäœæããŸãã
create index i1 on test (all_the_same); CREATE INDEX create index i2 on test (almost_unique); CREATE INDEX
OKããã¹ãæ§æã®æºåãã§ããŸããã èšç»ã¯ã©ãã§ããïŒ
explain select * from test where all_the_same = 123; QUERY PLAN ------------------------------------------------------------ Seq Scan on test (cost=0.00..1693.00 rows=100000 width=8) Filter: (all_the_same = 123) (2 rows) explain select * from test where almost_unique = 123; QUERY PLAN --------------------------------------------------------------- Index Scan using i2 on test (cost=0.29..8.31 rows=1 width=8) Index Cond: (almost_unique = 123) (2 rows)
ã芧ã®ãšãããPostgresã¯è³¢æãªéžæãããŸããã ããããããã§ã¯ããrows =ãã®æšå®å€ãéèŠã§ãã ã¯ãšãªãè¿ãããšãã§ããè¡æ°ãã©ã®ããã«ããŠç¥ãã®ã§ããããïŒ
çãã¯ã ANALYZEãŸãã¯VACUUM ANALYZEããŒã ã«ãããŸãã
ããŒãã«ã«ãANALYZEããé©çšãããšãPostgresã¯ãã©ã³ãã ãµã³ãã«ããååŸãïŒåŸã§è©³ãã説æããŸãïŒãçµ±èšæ å ±ãååŸããŸãã ããã¯ã©ã®ãããªçµ±èšæ å ±ã§ãã©ãã«ããããããèŠãããšãã§ããŸããïŒ ãã¡ãã次ã®ããšãã§ããŸãã
select * from pg_statistic where starelid = 'test'::regclass; -[ RECORD 1 ]----------------------------------------------------------------------------- starelid | 16882 staattnum | 1 stainherit | f stanullfrac | 0 stawidth | 4 stadistinct | 1 stakind1 | 1 stakind2 | 3 stakind3 | 0 stakind4 | 0 stakind5 | 0 staop1 | 96 staop2 | 97 staop3 | 0 staop4 | 0 staop5 | 0 stanumbers1 | {1} stanumbers2 | {1} stanumbers3 | [null] stanumbers4 | [null] stanumbers5 | [null] stavalues1 | {123} stavalues2 | [null] stavalues3 | [null] stavalues4 | [null] stavalues5 | [null] -[ RECORD 2 ]----------------------------------------------------------------------------- starelid | 16882 staattnum | 2 stainherit | f stanullfrac | 0 stawidth | 4 stadistinct | -0.92146 stakind1 | 1 stakind2 | 2 stakind3 | 3 stakind4 | 0 stakind5 | 0 staop1 | 96 staop2 | 97 staop3 | 97 staop4 | 0 staop5 | 0 stanumbers1 | {0.0001,0.0001,0.0001,0.0001,0.0001,0.0001,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05} stanumbers2 | [null] stanumbers3 | {-0.000468686} stanumbers4 | [null] stanumbers5 | [null] stavalues1 | {21606,27889,120502,289914,417495,951355,283,1812,3774,6028,6229,10372,12234,13291,18309,18443,21758,22565,26634,28392,28413,31208,32890,36563,39277,40574,44527,49954,53344,53863,56492,56715,60856,62993,64294,65275,65355,68353,71194,74718,77205,82096,82783,84764,85301,87498,90990,94043,97304,98779,101181,103700,103889,106288,108562,110796,113154,117850,121578,122643,123874,126299,129236,129332,129512,134430,134980,136987,137368,138175,139001,141519,142934,143432,143707,144501,148633,152481,154327,157067,157799,162437,164072,164337,165942,167611,170319,171047,177383,184134,188702,189005,191786,192718,196330,197851,199457,202652,202689,205983} stavalues2 | {2,10560,20266,31061,40804,50080,59234,69240,79094,89371,99470,109557,119578,130454,140809,152052,162656,173855,183914,194263,204593,214876,224596,233758,243246,253552,264145,273855,283780,294475,303972,314544,324929,335008,346169,356505,367395,376639,387302,397004,407093,416615,426646,436146,445701,455588,466463,475910,485228,495434,505425,515853,525374,534824,545387,554794,563591,573721,584021,593368,602935,613238,623317,633947,643431,653397,664177,673976,684042,694791,703922,714113,724602,735848,745596,754477,764171,772535,781924,791652,801703,812487,822196,831618,841665,850722,861532,872067,881570,891654,901595,910975,921698,931785,940716,950623,960551,970261,979855,989540,999993} stavalues3 | [null] stavalues4 | [null] stavalues5 | [null]
ãã®è¡šïŒpg_statisticïŒã¯ããã¡ããã ããã¥ã¡ã³ãã§èª¬æãããŠããŸãããããã§ãããªãäžå¯è§£ã§ãã ãã¡ããã ãœãŒã¹ã§éåžžã«æ£ç¢ºãªèª¬æãèŠã€ããããšãã§ããŸãããããã¯ïŒéåžžïŒæè¯ã®è§£æ±ºçã§ã¯ãããŸããã
幞ããªããšã«ãããèªã¿ããããã¥ãŒã§åãããŒã¿ãå«ããã®ããŒãã«ã®ãã¥ãŒããããŸãã
select * from pg_stats where tablename = 'test'; -[ RECORD 1 ]----------+------------------------------------------------------------------ schemaname | public tablename | test attname | all_the_same inherited | f null_frac | 0 avg_width | 4 n_distinct | 1 most_common_vals | {123} most_common_freqs | {1} histogram_bounds | [null] correlation | 1 most_common_elems | [null] most_common_elem_freqs | [null] elem_count_histogram | [null] -[ RECORD 2 ]----------+------------------------------------------------------------------ schemaname | public tablename | test attname | almost_unique inherited | f null_frac | 0 avg_width | 4 n_distinct | -0.92146 most_common_vals | {21606,27889,120502,289914,417495,951355,283,1812,3774,6028,6229,10372,12234,13291,18309,18443,21758,22565,26634,28392,28413,31208,32890,36563,39277,40574,44527,49954,53344,53863,56492,56715,60856,62993,64294,65275,65355,68353,71194,74718,77205,82096,82783,84764,85301,87498,90990,94043,97304,98779,101181,103700,103889,106288,108562,110796,113154,117850,121578,122643,123874,126299,129236,129332,129512,134430,134980,136987,137368,138175,139001,141519,142934,143432,143707,144501,148633,152481,154327,157067,157799,162437,164072,164337,165942,167611,170319,171047,177383,184134,188702,189005,191786,192718,196330,197851,199457,202652,202689,205983} most_common_freqs | {0.0001,0.0001,0.0001,0.0001,0.0001,0.0001,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05} histogram_bounds | {2,10560,20266,31061,40804,50080,59234,69240,79094,89371,99470,109557,119578,130454,140809,152052,162656,173855,183914,194263,204593,214876,224596,233758,243246,253552,264145,273855,283780,294475,303972,314544,324929,335008,346169,356505,367395,376639,387302,397004,407093,416615,426646,436146,445701,455588,466463,475910,485228,495434,505425,515853,525374,534824,545387,554794,563591,573721,584021,593368,602935,613238,623317,633947,643431,653397,664177,673976,684042,694791,703922,714113,724602,735848,745596,754477,764171,772535,781924,791652,801703,812487,822196,831618,841665,850722,861532,872067,881570,891654,901595,910975,921698,931785,940716,950623,960551,970261,979855,989540,999993} correlation | -0.000468686 most_common_elems | [null] most_common_elem_freqs | [null] elem_count_histogram | [null]
çŽ æŽãããã ããããã©ã®ãããªç¥èãåŒãåºãããšãã§ããŸããïŒ
åschemanameãtablenameãããã³attnameã¯æããã§ãã ç¶æ¿ã¯ããã®ããŒãã«ã®å€ã«ããã®åãç¶æ¿ããããŒãã«ã®å€ãå«ãŸããŠãããã©ãããåã«å ±åããŸãã
ãããã£ãŠãããŒãã«ãäœæããå ŽåïŒ
create table z () inherits (test);
ãããŠããã®ããŒãã«zã«ããŒã¿ãè¿œå ãããšããã¹ãããŒãã«ã®çµ±èšã«ãinherited = trueããšè¡šç€ºãããŸãã
æ®ãã®åã¯æ¬¡ã®ããšã瀺ããŠããŸãã
- null_frac-ãã®åã®NULLè¡æ°ã ããã¯åæ°ã§ãããããå€ã¯0ã1ã«ãªããŸãã
- avg_width-ãã®åã®ããŒã¿ã®å¹³åå¹ ïŒçŽãïŒãµã€ãºïŒã ããã¯ãå¹ ãäžå®ã®å ŽåïŒãã®äŸã§ã¯int4ã®ãããªïŒããã»ã©èå³æ·±ããã®ã§ã¯ãããŸããããå¯å€å¹ ïŒtext / varchar / numericãªã©ïŒãæã€ããŒã¿åã®å Žåã¯äŸ¿å©ã§ãã
- n_distinctã¯éåžžã«èå³æ·±ãå€ã§ãã æ£ïŒ1+ïŒã®å Žåãn_distinctã1ãšçããtrueã®all_the_sameåã®å Žåã«èŠãããããã«ãç°ãªãå€ã®åãªãæŠæ°ïŒåæ°ã§ã¯ãããŸããïŒïŒã«ãªããŸããè² ã®å Žåãæå³ã¯å€ãããŸãïŒn_distinctã¯è¡ã®å²åã¯äžæã§ãã ãããã£ãŠãalmost_uniqueã®å Žåãçµ±èšã§ã¯ãè¡ã®92.146ïŒ ãäžæã®å€ãæã£ãŠããããšã瀺åãããŸãïŒåã«ç€ºãã95.142ïŒ ãããããã«å°ããïŒã ç§ãèšåããåŸã§è©³çŽ°ã«èª¬æãããã©ã³ãã ãªãµã³ãã«ãã®ããã«ãå€ã¯ééã£ãŠããå¯èœæ§ããããŸãã
- most_common_valsã¯ããã®ããŒãã«ã®æãäžè¬çãªå€ã®é åã§ãã
- most_common_freqs-most_common_valsããã®å€ãèŠã€ããé »åºŠãå°æ°ã§ãããããæ倧å€ã¯1ã§ãïŒãã ããmost_common_valsã«ã¯å€ã1ã€ãããããŸããïŒã ããã§ãalmost_uniqueã§ãPostgresã¯å€21606ã27889ã120502ã289914ã417495ã951355ãæãé »ç¹ã«èŠã€ãããšãèããŠãããããšãããããŸãããããã§ã¯ãããŸããã ç¹°ãè¿ããŸããããã©ã³ãã ãã¿ãŒã³ãå¹æã¯éé£ããããšã§ãã
- histogram_bounds-ããŒã¿ã»ããå šäœãåãè¡æ°ã®ã°ã«ãŒãã«åå²ããïŒãŸãã¯åå²ããå¿ èŠããã-åã³ãã¹ãŠããã©ã³ãã ãã¿ãŒã³ãã«ããïŒå€ã®é åã ã€ãŸãã2ãã10560ã®éã®almost_uniqueè¡ã®æ°ã¯ã931785ãã940716ã®éã®almost_uniqueè¡ã®æ°ãšåãïŒå€ããå°ãªããïŒã§ãã
- çžé¢ã¯éåžžã«èå³æ·±ãçµ±èšã§ããããã£ã¹ã¯äžã®è¡ã®ç©ççãªãœãŒããšå€ã®éã«çžé¢ããããã©ããã瀺ããŸãã ãã®å€ã¯-1ãã1ãŸã§å€åã§ãã-1 / 1ã«è¿ãã»ã©çžé¢ã倧ãããªããŸãã ããšãã°ããi2ã䜿çšããCLUSTERãã¹ãããå®è¡ãããšãããŒãã«ãã»ãŒåºæã®é åºã§äžŠã¹æ¿ãããã0.919358ã®çžé¢é¢ä¿ãåŸãããŸãããããã¯ã以åã®å€-0.000468686ãããã¯ããã«åªããŠããŸãã
most_common_elemsãmost_common_elem_freqsãelem_count_histogramã¯most_common_valsãmost_common_freqsãhistogram_boundsãšåãã§ãããéã¹ã«ã©ãŒããŒã¿åïŒé åãtsvectorãªã©ïŒã®å Žåã§ãã
PostgreSQLã¯ãã®ããŒã¿ã«åºã¥ããŠãã¯ãšãªã®éžæãããéšåããè¿ãããè¡æ°ãæŠç®ãããã®æ å ±ã«åºã¥ããŠãã©ã¡ãã䜿çšããã®ãé©åãã決å®ããŸããseqã¹ãã£ã³ãã€ã³ããã¯ã¹ã¹ãã£ã³ããŸãã¯ããããããã€ã³ããã¯ã¹ã¹ãã£ã³ã ããŒãžãããšã-ããã·ã¥çµåãçµåçµåããŸãã¯ãã¹ãã«ãŒããªã©ãããé«éãªæäœãå¿ èŠã§ãã
äžèšã®ããŒã¿ãæ éã«æ€èšãããšãçåã«æããããããŸãããããã¯ããªãåºç¯ãªåºåããŒã¿ã®ã»ããã§ãããé åmost_common_vals / most_common_freqs / histogram_boundsã«ã¯å€ãã®å€ãå«ãŸããŠããŸãã ãªããããªã«ããããããã®ïŒ
çç±ã¯ç°¡åã§ã-èšå®ããã¹ãŠã§ãã postgresql.confã«ã¯ãdefault_statistics_targetå€æ°ããããŸãã ãã®å€æ°ã¯ããããã®é åã«æ ŒçŽããå€ã®æ°ãPostgresã«äŒããŸãã ç§ã®å ŽåïŒããã©ã«ãïŒããã®æ°ã¯100ã§ããããããç°¡åã«å€æŽã§ããŸãã postgresql.confãå€æŽãããã次ã®ããã«åã ã®åãå€æŽããŸãã
alter table test alter column almost_unique set statistics 5;
ALTERïŒããã³ANALYZEïŒã䜿çšãããšãpg_statsã®ããŒã¿ã¯å€§å¹ ã«ççž®ãããŸãã
select * from pg_stats where tablename = 'test' and not inherited and attname = 'almost_unique'; -[ RECORD 1 ]----------+--------------------------------------------------------- schemaname | public tablename | test attname | almost_unique inherited | f null_frac | 0 avg_width | 4 n_distinct | -0.92112 most_common_vals | {114832,3185,3774,6642,11984} most_common_freqs | {0.0001,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05} histogram_bounds | {2,199470,401018,596414,798994,999964} correlation | 1 most_common_elems | [null] most_common_elem_freqs | [null] elem_count_histogram | [null]
çµ±èšã¿ãŒã²ãããå€æŽãããšãå¥ã®å¹æããããŸãã
èŠããŠãããŸãããã å§ããããã«ãALTER TABLEã䜿çšããŠè¡ã£ãçµ±èšã®å€æŽãããŒã«ããã¯ããŸãã
alter table test alter column almost_unique set statistics -1;
次ã®æé ãå®è¡ããŸãã
$ analyze verbose test; INFO: analyzing "public.test" INFO: "test": scanned 443 of 443 pages, containing 100000 live rows and 0 dead rows; 30000 rows in sample, 100000 estimated total rows ANALYZE $ alter table test alter column almost_unique set statistics 10; ALTER TABLE $ alter table test alter column all_the_same set statistics 10; ALTER TABLE $ analyze verbose test; INFO: analyzing "public.test" INFO: "test": scanned 443 of 443 pages, containing 100000 live rows and 0 dead rows; 3000 rows in sample, 100000 estimated total rows ANALYZE
2çªç®ã®åæã§ã¯ãæåã®30,000è¡ã§ã¯ãªã3,000è¡ãããã¹ããããŠããªãããšã«æ³šæããŠãã ããã
ããã¯ãã©ã³ãã ãµã³ãã«ãã§ãã
ãã¹ãŠã®è¡ã®åæã¯ãäžèŠæš¡ãŸãã¯å€§èŠæš¡ã®ããŒãã«ã§ã¯éåžžã«é«äŸ¡ã§ãã
ãããã£ãŠãPostgresã¯ããã¹ããŒãã«ãªã£ãŠããŸãã
ãŸããããŒãã«ã®ããŒãžã®ã©ã³ãã ãªéšåãèªã¿åããŸãïŒåããŒãžã¯8kBã®ããŒã¿ãæãåºããŠãã ããïŒã æ£ç¢ºã«ãããã§ããïŒ 300 * statistics_targetã
ããã¯ãdefault_statistics_target = 100ã®å Žåã30,000ããŒãžãèªã¿åãããšãæå³ããŸãïŒç§ã®ããŒãã«ã«ã¯ããã»ã©å€ããªãã®ã§ãPostgresã¯ãããããã¹ãŠèªã¿åããŸãïŒã
ãããã®ããŒãžãããANALYZEã¯ã©ã€ãããã³ãããã©ã€ã³ã«é¢ããæ å ±ã®ã¿ãååŸããŸãã 次ã«ãã©ã³ãã ãªè¡ãã¿ãŒã³ã«é¢ããããŒã¿ïŒåã³300 *çµ±èšã¿ãŒã²ããïŒãåä¿¡ãããã®ããŒã¿ã«åºã¥ããŠåã®çµ±èšãèšç®ããŸãã
ç§ã®å ŽåãããŒãã«ã«ã¯100,000è¡ãããŸããããdefault_statistics_target = 100ã®å Žåãåæãããã®ã¯3åã®1ã ãã§ãã ãŸããçµ±èšã¿ãŒã²ããã®å€ãèæ ®ã«å ¥ãããšãåæãããè¡ã®æ°ã¯ããã«å°ãªããªãã3000ã«ãªããŸãã
ããªãã¯èšãããšãã§ããŸãïŒOKãããããã®å Žåããããã®çµ±èšã¯äžæ£ç¢ºã§ãã ã¹ãã£ã³ãããè¡ã®ãããã«ããéåžžã«äžè¬çãªå€ã衚瀺ãããªãå ŽåããããŸãã ãã¡ãããããªãã¯æ£ããã§ãã å¯èœã§ãã ããŸããããŸãããã ã©ã³ãã ãªããŒã¿ãåãåããŸãã ä»ã®ãã¹ãŠã®è¡ã«ååšããäœããã®å€ãæã€åäžè¡ãååšããªãããŒãã«ã®xïŒ ãååŸããå¯èœæ§ã¯ç¡èŠã§ããŸãã
ãŸããå Žåã«ãã£ãŠã¯ãåæã®å®è¡ã«ãã£ãŠã¯ãšãªããå£ãããããšãæå³ããŸãã ããšãã°ãä»ã®ããŒãžã®çµ±èšæ å ±ãååŸãããšãäžéšã®å€ãã¹ããããããããšãããããŸãïŒãŸãã¯ãã®é-most_common_valsã§ããŸãäžè¬çãªå€ãååŸããªããããPostgresãé©åãªããŒãž/è¡ãéžæããŠãããã衚瀺ããŸãïŒã ãããŠããã®ãããªçµ±èšã«åºã¥ããŠãPgã¯æé©ã§ã¯ãªãèšç»ãçæããŸãã
ãã®ãããªç¶æ³ã«ééããå Žåãããã解決ããã®ã¯éåžžã«ç°¡åã§ã-çµ±èšã¿ãŒã²ãããå¢ãããŸãã ããã«ãããanalyzeãäžçæžåœäœæ¥ããããå€ãã®è¡ãã¹ãã£ã³ããããã«åŒ·å¶ãããããããããåã³çºçããå¯èœæ§ã¯ããã«å°ãªããªããŸãã
ãã ãã倧ããªçµ±èšã¿ãŒã²ããå€ãèšå®ãããšãç¹å®ã®æ¬ ç¹ããããŸãã æåã«ãANALYZEã¯äžçæžåœåãå¿ èŠããããŸãããããã¯æŸåã®åé¡ã§ãããããããŸãæ°ã«ããŸããïŒéåžžïŒã äž»ãªåé¡ã¯ãpg_statisticã®ããŒã¿ãå€ãã»ã©ãPgã¹ã±ãžã¥ãŒã©ãŒã«ããå€ãã®ããŒã¿ãèæ ®ããå¿ èŠãããããšã§ãã ãããã£ãŠãdefault_statistics_targetãæ倧10,000ã«èšå®ããã®ãã©ããªã«é åçã§ãã£ãŠããå®éã«ã¯ããã®å€ãéåžžã«é«ãããŒã¿ããŒã¹ã«ã¯ééããŠããŸããã
çŸåšã®100ã¯ãããŒãžã§ã³8.4ããããã©ã«ãã§ã€ã³ã¹ããŒã«ãããŸãã 以åã®ããŒãžã§ã³ã§ã¯ãããã©ã«ãå€ã¯10ã§ããããircã«ã¯ãããå¢ããããã®ãã³ãããã°ãã°ãããŸããã 100ã®å€ã§ããã¹ãŠãå€ããå°ãªããæ§æãããŠããŸãã
ç§ãæåŸã«è©±ããªããã°ãªããªãããšã¯ãç§ã¯ããŸãæãã§ããŸããããPostgresã¹ã±ãžã¥ãŒã©ãŒãç°ãªãæäœã䜿çšããããã«ããèšå®ã§ãã
æåã«ããªãããã«ã€ããŠè©±ããããªãã®ãã説æããŸããããã¯ç°¡åã«æªçšãããå¯èœæ§ãããããšã¯ç¢ºãã§ãã ãã®ããããããã®èšå®ã¯ãåé¡ã解決ããããã§ã¯ãªããåé¡ãèŠã€ããããã«å¿ èŠã§ãã åäœã¢ãŒãã§ãããã䜿çšããã¢ããªã±ãŒã·ã§ã³ã¯ãå°ãªããšããç ŽæããçãããããŸãã ãããŠãã¯ããç§ã¯æã ãããããªããã°ãªããªãããšãç¥ã£ãŠããŸãã ãããããã®ãæã ãã¯ãã£ãã«èµ·ãããŸããã
ç§ã¯ããªãã«èŠåããã®ã§ãäœãã§ãããèŠãŠã¿ãŸãããã
postgresql.confã«ã¯ãããã€ãã®ãªãã·ã§ã³ããããŸãã
enable_bitmapscan = on enable_hashagg = on enable_hashjoin = on enable_indexscan = on enable_indexonlyscan = on enable_material = on enable_mergejoin = on enable_nestloop = on enable_seqscan = on enable_sort = on enable_tidscan = on
ãããã®èšå®ã¯ãéžæããæäœãç¡å¹ã«ããããã«å¿ èŠã§ãã
ããšãã°ãenable_seqscanãfalseã«åãæ¿ãããšïŒSQLã»ãã·ã§ã³ã§SETã³ãã³ãã䜿çšããŠå®è¡ã§ããŸããpostgresql.confãå€æŽããå¿ èŠã¯ãããŸããïŒãã¹ã±ãžã¥ãŒã©ã¯ã·ãŒã±ã³ã·ã£ã«ã¹ãã£ã³ãåé¿ããããã«å¯èœãªéããã¹ãŠã䜿çšããŸãã
ãŸããã·ãŒã±ã³ã·ã£ã«ã¹ãã£ã³ãé¿ããããšãã§ããªãå ŽåãããããïŒããšãã°ãããŒãã«ã«ã€ã³ããã¯ã¹ããªãå ŽåïŒããããã®èšå®ã¯å®éã«æäœãç¡å¹ã«ããã®ã§ã¯ãªãã䜿çšã«è«å€§ãªã³ã¹ããããããŸãã
äŸãæããŸãã ãã¹ããã¿ãŒã³ã«é¢ããŠã¯ããall_the_same = 123ãã§æ€çŽ¢ãããšãè²»çšãããããªããããé 次ã¹ãã£ã³ã䜿çšãããããšãããããŸãã
explain select * from test where all_the_same = 123; QUERY PLAN ------------------------------------------------------------ Seq Scan on test (cost=0.00..1693.00 rows=100000 width=8) Filter: (all_the_same = 123) (2 rows)
ãã ããseqã¹ãã£ã³ãç¡å¹ã«ããå ŽåïŒ
set enable_seqscan = false; SET explain select * from test where all_the_same = 123; QUERY PLAN ----------------------------------------------------------------------- Index Scan using i1 on test (cost=0.29..3300.29 rows=100000 width=8) Index Cond: (all_the_same = 123) (2 rows)
ã€ã³ããã¯ã¹ã¹ãã£ã³ãã䜿çšããŠåãããŒã¿ãååŸããããã®æšå®ã³ã¹ãã¯2åé«ãããšãããããŸãïŒ3300.29察1693ïŒã
i1ã€ã³ããã¯ã¹ãåé€ããå ŽåïŒ
drop index i1; DROP INDEX set enable_seqscan = false; SET explain select * from test where all_the_same = 123; QUERY PLAN ----------------------------------------------------------------------------- Seq Scan on test (cost=10000000000.00..10000001693.00 rows=100000 width=8) Filter: (all_the_same = 123) (2 rows)
ãŸããã·ãŒã±ã³ã·ã£ã«ã¹ãã£ã³ä»¥å€ã«ä»ã®ãªãã·ã§ã³ããªãå ŽåïŒãã®ã€ã³ããã¯ã¹ã«ã¯ããŒãã«å ã®ãã¹ãŠã®è¡ãžã®ãã€ã³ã¿ãŒãããã«ãããããããPostgresãi2ã§ã€ã³ããã¯ã¹ã¹ãã£ã³ãéžæããªãã£ãã®ã¯èå³æ·±ãããšã§ãïŒãã³ã¹ãã10,ââ000,000,000ã«æ¥éš°ããŸãã-ããã¯enable_ *ã§ã= falseããã³ãããŸããã
ããããã¹ãŠã ãšæããŸãã ã·ãªãŒãºå šäœãèªããšãäœãèµ·ãã£ãŠããã®ããããã«éèŠãªã®ã¯ãªãããç解ããã®ã«ååãªç¥èãåŸãããŠããã¯ãã§ãã