Webã¢ããªã±ãŒã·ã§ã³ã§äžè¬çãªããŒãžããŒã·ã§ã³ã¯ãéåççã«ç°¡åã«å®è£
ã§ãããšããäºå®ã«é©ããããããŸããã ãã®èšäºã§ã¯ãããŸããŸãªãµãŒããŒåŽã®ããŒãžããŒã·ã§ã³æ¹æ³ã詊ããŠãPostgreSQLã§äœ¿çšããå Žåã®äŸ¿å©ãã«ã€ããŠèª¬æããŸãã ãã®èšäºã¯ããããŸã§èŠãããšã®ãªãææ³ãã€ãŸãç©çã¯ã©ã¹ã¿ãªã³ã°ãšããŒã¿ããŒã¹çµ±èšã³ã¬ã¯ã¿ãŒã«äŸåããææ³ãªã©ãç¶æ³ã«å¿ããŠããé©åãªææ³ãçè§£ããã®ã«åœ¹ç«ã¡ãŸãã
ç¶è¡ããåã«ãã¢ããªã±ãŒã·ã§ã³åŽã®ããŒãžããŒã·ã§ã³ã«èšåããŠãã ããã äžéšã®ã¢ããªã±ãŒã·ã§ã³ã¯ããµãŒããŒæ
å ±ã®ãã¹ãŠïŒãŸãã¯ã»ãšãã©ïŒãã¯ã©ã€ã¢ã³ãã«è»¢éããããã®ããŒãžã§å
±æããŸãã å°éã®ããŒã¿ã®å Žåãã¢ããªã±ãŒã·ã§ã³åŽã®ããŒãžããŒã·ã§ã³ãé©åãªéžæãšãªããHTTPåŒã³åºãã®æ°ãæžããŸãã ã¬ã³ãŒããæ°åã«ãªãå§ãããšããã®ã¢ãããŒãã¯å®çšçã§ã¯ãªããªããŸãã ãµãŒããŒåŽã®ããŒãžããŒã·ã§ã³ã«ã¯æ¬¡ã®å©ç¹ããããŸãã
- ã¹ã¿ãŒãããŒãžã®èªã¿èŸŒã¿ãé«éå
- å
±æããŒã¿ã倿Žããããšãã®ããé«ã粟床
- 倧éã®ããŒã¿ã®é«éæäœ
- ããžãã¹ããžãã¯ã®ã«ãã»ã«å
- éããããªãœãŒã¹ã®ã¯ã©ã€ã¢ã³ãã§ã®ããã©ãŒãã³ã¹ã®åäž
PostgreSQLã¯ãç¹å®ã®ããŒãžã®ã¢ã¯ã»ã¹ãã¿ãŒã³ã®ãµããŒããšåæ§ã«ãéåºŠãæŽåæ§ïŒã¬ã³ãŒãã倱ããªãïŒãç°ãªãããµãŒããŒåŽã®ç¹å®ã®ããŒãžããŒã·ã§ã³æè¡ãæäŸããŸãã ãã¹ãŠã®ã¡ãœããããã¹ãŠã®ç¶æ³ã§æ©èœããããã§ã¯ãªããäžéšã®ã¡ãœããã¯ç¹å¥ãªããŒã¿ãŸãã¯ã¯ãšãªãå¿
èŠãšããŸãã ã¡ãœãããäžè¬çãªé åºã§æ€èšããŸãããã¹ãŠã®ã¯ãšãªã§æ©èœããã¡ãœããããéå§ããé åºä»ããããããŒã¿ãå¿
èŠãšããã¡ãœããã§ç¶ç¶ããŸãã æçµçã«ãå
éšã®PostgreSQLããã€ã¹ã«åºã¥ããããã€ãã®ãšããŸããã¯ãªæ¹æ³ã«ãªããŸãã
ã«ã¹ã¿ã ã¯ãšãªã®åå²
éçãªãã»ãã
æãåçŽãªããŒãžããŒã·ã§ã³æ¹æ³ã§ãããªããããªãã»ãããæãå±éºã§ãã æ®å¿µãªãããããã¯Webéçºãã¥ãŒããªã¢ã«ã®åºç€ã®1ã€ã§ãã ãªããžã§ã¯ããªã¬ãŒã·ã§ãã«ãããã³ã°ïŒORMïŒã©ã€ãã©ãªã«ãããSQLAlchemy
.sliceïŒ1ã3ïŒããActiveRecord
.limitïŒ1ïŒ.offsetïŒ3ïŒããSequelize
.findAllïŒ{ãªãã»ããïŒ3ãå¶éïŒ1}ïŒ ã ã©ãã§ãlimit-offsetã䜿çšãããããšã¯å¶ç¶ã§ã¯ãããŸããããã以äžã®å€æŽãããã«ããªã¯ãšã¹ãã«æ·»ä»ã§ããŸãã
å¶éãšãªãã»ããã®ORMã¡ãœããã¯1ã€ã§ãããããŒãžããŒã·ã§ã³ã®è£å©ã©ã€ãã©ãªã¯ããã«æ¬ºãããšãã§ããŸãã ããšãã°ã人æ°ã®ããKaminari Rubyã©ã€ãã©ãªã¯ããã©ã«ãã§limit-offsetã䜿çšããé«ã¬ãã«ã®ã€ã³ã¿ãŒãã§ãŒã¹ã®èåŸã«é ããŠããŸãã
ãã®ææ³ã«ã¯ãçµæã®äžè²«æ§ãšãã€ã¢ã¹ã®éå¹çæ§ãšãã2ã€ã®å€§ããªåé¡ããããŸãã äžè²«æ§ã¯ãçµæãæž¡ãããšã§ãçç¥ãç¹°ãè¿ããããã«åèŠçŽ ãå³å¯ã«1ååãåãå¿
èŠããããšããäºå®ã«ãããã®ã§ãã ãã€ã¢ã¹ã®éå¹çæ§ã¯ãçµæã倧ããªãã€ã¢ã¹ã«ã·ãããããšãã«çºçããé
å»¶ã«é¢é£ããŠããŸãã
ãªããããªãã»ããããŒãžããŒã·ã§ã³ãççŸããå¯èœæ§ãããæ¹æ³ã次ã«ç€ºããŸãã ãŠãŒã¶ãŒãããŒãž
nããããŒãž
n + 1ã«ç§»åããåæã«æ°ããèŠçŽ ãããŒãž
nã«æ¿å
¥ããããšããŸãã ããã«ãããè€è£œïŒããŒãž
nã®æåŸã®èŠçŽ ãããŒãž
n + 1ã«æŒãåºãããïŒãšã¹ãããïŒæ°ããèŠçŽ ïŒã®äž¡æ¹ãçºçããŸãã ãããã¯ããŠãŒã¶ãŒãããŒãž
n + 1ã«ç§»åããæç¹ã§èŠçŽ
nãåé€ããããšããŸãã ããŒãž
n + 1ã®ããªããŒããããéå§èŠçŽ ã¯ããŒãž
nã«ç§»åããã¹ããããããŸãã
ä»ãéå¹çæ§ã®ãããã¯ã«ã€ããŠã 倧ããªã·ããã¯æ¬åœã«é«äŸ¡ã§ãã ã€ã³ããã¯ã¹ãããå Žåã§ããããŒã¿ããŒã¹ã¯è¡å
šäœãã«ãŠã³ãããŠã¹ãã¬ãŒãžå
šäœãã¹ãã£ã³ããå¿
èŠããããŸãã ã€ã³ããã¯ã¹ã䜿çšããã«ã¯ãå€ã§åããã£ã«ã¿ãªã³ã°ããå¿
èŠããããŸããããã®å Žåãåã®å€ã«é¢ä¿ãªããç¹å®ã®è¡æ°ãå¿
èŠã§ãã ããã«ãè¡ã¯ä¿åäžã«åããµã€ãºã§ããå¿
èŠã¯ãªãããããã®äžéšã¯ãã£ã¹ã¯äžã«ååšããå ŽåããããŸãããå逿žã¿ãšããŠããŒã¯ãããŠãããããããŒã¿ããŒã¹ã¯åçŽãªç®è¡ã䜿çšããŠãã£ã¹ã¯é åãèŠã€ããçµæã®èªã¿åããéå§ã§ããŸããã ã¹ããŒããŠã³ã枬å®ããŸãããã
æšå®ã³ã¹ãã¯éåžžã«äœãã§ãã
QUERY PLAN
ãªãã»ãã= 1000ãéžæãããšãã³ã¹ãã19ã«ãã©ã³ã¿ã€ã ã0.609ããªç§ã«å€æŽãããŸãã ãªãã»ãã= 5000000ã«ãªããšããã«ãã³ã¹ãã¯ãã§ã«92734ã«ãªããå®è¡æéã¯758.484ããªç§ã«ãªããŸãã
ãããã®åé¡ã¯ããªããããªãã»ããæ¹åŒãããªãã®å Žåã«é©çšã§ããªãããšãå¿
ãããæå³ããŸããã äžéšã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããŠãŒã¶ãŒã¯éåžžãçµæå
ã®å€ãã®ããŒãžãééããŸããããŸãããµãŒããŒåŽã®ããŒãžå¶éã䜿çšããããšãã§ããŸãã ã¢ããªã±ãŒã·ã§ã³ã§ããŒã¿ã®äžæŽåãšããŒãžå¶éãåé¡ã«ãªããªãå Žåã¯ãlimit-offsetã¡ãœãããéåžžã«é©ããŠããŸãã
䜿çšããå ŽåïŒLimit-Offsetã å¶éãããããŒãžããŒã·ã§ã³ã®æ·±ããšäžè²«æ§ã®èš±å®¹ç¯å²ãæã€ã¢ããªã±ãŒã·ã§ã³ã
ã«ãŒãœã«
æ¬ ç¹ã«ãããããããlimit-offsetã¡ãœããã«ã¯ããµãŒããŒã«åœ±é¿ããªããšãã圢ã§ãã©ã¹ããããŸãã ãã®ã¢ãããŒããšã¯å¯Ÿç
§çã«ãããŒãžããŒã·ã§ã³ã®å¥ã®æ¹æ³ã§ããã«ãŒãœã«ããããŸãã ãã€ã¢ã¹ãšåæ§ã«ãã«ãŒãœã«ã¯ã©ã®ãªã¯ãšã¹ãã§ã䜿çšã§ããŸããããµãŒããŒãšHTTPã¯ã©ã€ã¢ã³ããä»ãããã©ã³ã¶ã¯ã·ã§ã³ããã®åå¥ã®æ¥ç¶ãå¿
èŠã§ãããšããç¹ã§ç°ãªããŸãã
ã«ãŒãœã«ã®äœ¿ç𿹿³ã¯æ¬¡ã®ãšããã§ãã
ã«ãŒãœã«ã«ã¯ãã¯ãšãªã®ããŒãžããŒã·ã§ã³ã®äžè²«æ§ãšããæãŸããããããã£ãããããã©ã³ã¶ã¯ã·ã§ã³ã®éå§æã«ããŒã¿ããŒã¹ã«ååšããçµæã瀺ããŸãã ãã©ã³ã¶ã¯ã·ã§ã³
åé¢ã¬ãã«ã«ãããããŒãžåå²ãããçµæãå€ãããªãããšãä¿èšŒãããŸãã
åããŒãžããŒã·ã§ã³ã¢ãããŒãã«ã¯åŒ±ç¹ããããã«ãŒãœã«ãäŸå€ã§ã¯ãããŸããããããã¯ãªãœãŒã¹ã®äœ¿çšãšã¯ã©ã€ã¢ã³ã/ãµãŒããŒãã³ãã«ã«äŸåããŠããŸãã éããŠããåãã©ã³ã¶ã¯ã·ã§ã³ã¯ãããŒã¿ããŒã¹ã«å²ãåœãŠããããªãœãŒã¹ãæ¶è²»ãã倿°ã®ã¯ã©ã€ã¢ã³ãã«å¯Ÿå¿ã§ããŸããã ãã¡ããããã©ã³ã¶ã¯ã·ã§ã³ã®å€éšã«ååšããå¯èœæ§ã®ããWITH HOLDã«ãŒãœã«ããããŸãããããŒã¿ãå
·äœåããå¿
èŠãããããããããã®ãšã©ãŒã«ãããã«ãŒãœã«ã¯å
éšãããã¯ãŒã¯ãªã©ã®çãç¯å²ã®ç¶æ³ã«ã®ã¿é©ããŠããŸãã
ã«ãŒãœã«ãžã®HTTPéä¿¡ã®è¿œå ã¯è€éã§ãã ãµãŒããŒã¯ãããŒã¯ã³ãéããŠããŸãã¯ã»ãã·ã§ã³å
ã®ã¯ã©ã€ã¢ã³ãã®IPã¢ãã¬ã¹ãªã©ã®èå¥åãä¿åããããšã«ãã£ãŠããªã¯ãšã¹ãéã§ã¯ã©ã€ã¢ã³ããèå¥ããå¿
èŠããããŸãã ãµãŒããŒã¯ãããŠã³ã¿ã€ã ã®ããã«ãã©ã³ã¶ã¯ã·ã§ã³ããã€è§£æŸããããæ±ºå®ããå¿
èŠããããŸãã æåŸã«ãã¯ã©ã€ã¢ã³ãã¯æ¯åç¹å®ã®ãµãŒããŒã«æ¥ç¶ããå¿
èŠãããããããµãŒããŒã®è² è·ã忣ããããšã¯å°é£ã«ãªããŸãã
䜿çšããå ŽåïŒã«ãŒãœã«ã ç¹ã«çµæã®äžè²«æ§ãéèŠãªå Žåã«ããªã¯ãšã¹ãã倿°ãšå€æ°ã®é åºã§ããŒãžã«åå²ãããåäžãµãŒããŒäžã®ãããã¯ãŒã¯å
ã®ã¢ããªã±ãŒã·ã§ã³ã
é åºä»ãã¯ãšãªã®ããŒãžããŒã·ã§ã³
ããŒããŒãžããŒã·ã§ã³
äžèšã®ææ³ã¯ãé åºä»ããããŠããªãã¯ãšãªãå«ããããããã¿ã€ãã®ã¯ãšãªçµæãããŒãžåå²ã§ããŸãã ãã®ã³ãã¥ããã£ãæŸæ£ããæºåãã§ããŠããã°ãæé©åã®ã¡ãªããã享åã§ããŸãã ç¹ã«ãã€ã³ããã¯ã¹åã§ãœãŒãããå ŽåããŠãŒã¶ãŒã¯çŸåšã®ããŒãžã®å€ã䜿çšããŠã次ã®ããŒãžã«è¡šç€ºãããªããžã§ã¯ããéžæã§ããŸãã ããã¯ãããŒã»ããããŒãžããŒã·ã§ã³ãšåŒã°ããŸãã
ããšãã°ãäŸã«æ»ããŸãããã
ç§ã®ã©ã³ãã ããŒã¿ã§ã¯ã次ã®çµæãè¿ãããŸãã
n | description
ããã§ããŠãŒã¶ãŒã¯çµæããæå€§nãèŠãŠãããã䜿çšããŠæ¬¡ã®ããŒãžãåŒã³åºãããšãã§ããŸãã
SELECT * FROM medley WHERE n > 5 ORDER BY n ASC LIMIT 5;
n> 5000000ã§ãã£ã«ã¿ãªã³ã°ããå Žåã§ããlimit-offsetã®äŸãããé«éã«æ©èœããŸãã
QUERY PLAN
ãã®ããŒãžããŒã·ã§ã³ã¯é«éã§ãããŒã¿ã®æŽåæ§ãä¿èšŒããŸãã çŸåšã®ããŒãžã«è¿œå /åé€ããŠããçµæã¯å€æŽãããŸããã ãã®æ¹æ³ã®2ã€ã®åŒ±ç¹ã¯ãã©ã³ãã ã¢ã¯ã»ã¹ã®æ¬ åŠãšãã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®æ¥ç¶ã®å¯èœæ§ã§ãã
äžè¬ã«ãåã®ããŒãžã«ã¢ã¯ã»ã¹ããŠæå€§èŠçŽ ãæ±ºå®ããã«ãéžæããããŒãžã«ç§»åããæ¹æ³ã¯ãããŸããã ãã ããç¹å®ã®æ¡ä»¶äžã§ã¯ãããè¯ãçµæãåŸãããŸãã ã€ã³ããã¯ã¹ä»ãåã®å€ãåçã«åæ£ããŠããå ŽåïŒãŸãã¯ã¹ããŒã¹ãå«ãŸãªã飿¥ããæ°å€ã®æ¹ãè¯ãå ŽåïŒããŠãŒã¶ãŒã¯æ°åŠçãªèšç®ãå®è¡ããŠç®çã®ããŒãžãèŠã€ããããšãã§ããŸãã
EXPLAIN ANALYZE SELECT max(n) FROM medley; QUERY PLAN
ããŒå€ã®æ¹ããŒãžã®å¥ã®åé¡ã§ããã¯ã©ã€ã¢ã³ã/ãµãŒããŒæ¥ç¶ã«ã¯æ³šæãå¿
èŠã§ãã æåã¯ããŠãŒã¶ãŒã¯ã©ã®åã«ã€ã³ããã¯ã¹ãä»ããããŠããããç¥ããŸããã ãµãŒããŒã¯ãã¯ã©ã€ã¢ã³ãã«å泚æãèš±å¯ããã®ã§ã¯ãªãããšã³ããã€ã³ãã«äžå®ã®çµæãæäŸããå¯èœæ§ããããŸãã ã¯ã©ã€ã¢ã³ãã«æäŸãããã³ãŒãã¯ãã©ã®åãé åºä»ããããŠããããç¥ããªãå ŽåãããããµãŒããŒã¯æ¬¡ã®ããŒãžãèŠæ±ããæ¹æ³ã«é¢ãããã³ããæäŸããå¿
èŠããããŸãã
RFC5988ã¯ãåãšæ¬¡ã®HTTPãªã³ã¯ã®é¢ä¿ãå®çŸ©ããŠããŠãŒã¶ãŒãåŸããªã³ã¯ããšã³ã³ãŒãããŸãã
éåžžããŠãŒã¶ãŒã¯æ
å ±ããŒãžã«çŽç·çã«ã¢ã¯ã»ã¹ãããããéåžžãè² è·ã®é«ãWebãµãŒããŒäžã®ã¬ã³ãŒãã®ããŒãžä»ãã«ã¯ããŒå€ã®ããŒãžä»ããåªå
ãããŸãã
䜿çšããå ŽåïŒããŒå€ã«ããããŒãžããŒã·ã§ã³ã æ¯èŒã®ããã«ã€ã³ããã¯ã¹ãä»ããããåããé çªã«ããŒã¿ãæäŸããã¹ã±ãŒã©ãã«ãªã¢ããªã±ãŒã·ã§ã³ã ãã£ã«ã¿ãªã³ã°ããµããŒãããŸãã
颚å€ããã§å°éçãªããŒãžããŒã·ã§ã³
ã¯ã©ã¹ã¿ãŒåTIDã¹ãã£ã³
äœã¬ãã«ã®PostgreSQL颿°ã䜿çšããŠãç¹å¥ãªç¶æ³åãã®ã«ã¹ã¿ã ããŒãžããŒã·ã§ã³ã¡ãœãããååŸã§ããŸãã ããšãã°ã次ã®å ŽåãããŒã¿ã«æ¬åœã«ã©ã³ãã ã«ã¢ã¯ã»ã¹ã§ããŸãã
- ããŒãžãåããµã€ãºã«ããå¿
èŠã¯ãããŸãã
- ããŒãžåºåãæååã®åäžæ³šæã®ã¿ããµããŒãããŸã
ç§Theã¯ããã£ã¹ã¯äžã®ããŒã¿ããŒã¹ã®ããŒãžããŸãã¯ãã£ã¹ã¯äžã®ãããã®ããŒãžã®ç¹å®ã®éšåã«ãªã³ã¯ãããŠããè¿ãããããŒãžãéžæããããšã§ãã PostgreSQLããŒã¿ããŒã¹ã®åããŒãã«ã«ã¯ãctidãšåŒã°ããç§å¯ã®åãå«ãŸãããã®è¡ãèå¥ããŸãã
SELECT ctid, * FROM medley WHERE n <= 10; ctid | n | description
åctidã¯æ¬¡ã®ãšããã§ãïŒïŒããŒãžãè¡ïŒã PostgreSQLã¯ctidã«ãã£ãŠéåžžã«è¿
éã«è¡ãååŸã§ããŸããå®éããããã€ã³ããã¯ã¹ã®ä»çµã¿ã§ããåå€ãctidã«ãã€ã³ãããŸãã
PostgreSQLã¯tidåã«åºã¥ããŠé åºé¢ä¿ãå®çŸ©ããŸãããäžçåŒããctidãå¹ççã«ååŸã§ããªãããšã«æ³šæããŠãã ãã
EXPLAIN ANALYZE SELECT count(1) FROM medley WHERE ctid >= '(0,1)'::tid AND ctid < '(1,0)'::tid; QUERY PLAN
ã¬ã³ãžã³ã°ã¯æ©èœããŸãããããã£ã¹ã¯äžã®ããŒãžãããã¹ãŠã®è¡ãå¹ççã«ç
§äŒããæ¹æ³ããŸã ãããŸãã åããŒãžã«ã¯ãcurrent_settingïŒ 'block_size'ïŒããŒã¿ãã€ãïŒéåžž8kïŒãå«ãŸããŸãã è¡ã¯32ããããã€ã³ã¿ãŒã«ãã£ãŠãªã³ã¯ãããŠãããããã»ãšãã©ã®å Žåãblock_size /ããŒãžããã4è¡ãå¿
èŠã§ãã ïŒå®éãéåžžãè¡ã¯æå°ãµã€ãºãããåºãããããã¯ãµã€ãºã®4åã®1ãããŒãžäžã®è¡ã®äžéšå¢çãæäŸããŸããïŒæ¬¡ã®ã·ãŒã±ã³ã¹ã¯ãjçªç®ã®ããŒãžã§ãã¹ãŠã®ctidãçæããŸãã
SELECT ('(' || j || ',' || si || ')')::tid FROM generate_series(0,current_setting('block_size')::int/4) AS s(i);
ããã䜿çšããŠããŒãããŒãžã®äŸã®ãã¹ãŠã®è¡ãååŸããŸãã
SELECT * FROM medley WHERE ctid = ANY (ARRAY (SELECT ('(0,' || si || ')')::tid FROM generate_series(0,current_setting('block_size')::int/4) AS s(i) ) );
ã¹ã±ãžã¥ãŒã©ã¯ããã®ãªã¯ãšã¹ããå®è¡ããã³ã¹ããcost = 25.03..65.12ã«æ±ºå®ãã2.765msã§å®è¡ããŸãã ããŒãžçªå·10000ããªã¯ãšã¹ãããŠãåãã³ã¹ãã«ãªããŸãã ãããã£ãŠãç§ãã¡ã¯æ¬åœã«ã©ã³ãã ã¢ã¯ã»ã¹ãååŸããŸãããªããããæããŸãããïŒ
3ã€ã®ããã«ããã¯ããããŸãã
- è¡ãåé€ããããšãããŒãžã«ç©Žãæ®ããŸãã
- è¡ã®é åºã¯éèŠã§ã¯ãããŸããã ããŒã¿ããŒã¹ã¯ãè¡ãåé€ããŠæ®ã£ã穎ã«è¡ãæ¿å
¥ããŸããããã«ãããè¡ãé åºã©ããã«ãªããŸããã
- ãµããŒããããŠããªãå Žæ
ç¶æ³ã«ãã£ãŠã¯ãããã¯åé¡ã§ã¯ãããŸããã 1ã€ã®ã±ãŒã¹ã¯ããŒã¿ã§ãããèªç¶ãªé åºã¯ãæéééã®å¢åããŒã¿ã®ã¿ãªã©ãããŒã¿ããŒã¹ã«è¿œå ããé åºãšçžé¢ããŠããŸãã ãã1ã€ã¯ãé »ç¹ã«å€æŽãããªãããŒã¿ã§ãã ããã¯ãCLUSTERã³ãã³ãã䜿çšããŠããŒãžäžã®è¡ã®ã¬ã€ã¢ãŠããå¶åŸ¡ã§ãããšããäºå®ã«ãããã®ã§ãã
äŸã«æ»ããŸãããã ãã£ã¹ã¯äžã®ãã®è¡ã¯ãããŒã¿ããŒã¹ã«è¿œå ããé åºã§ãããããæé ã§nåããšã«äžŠã¹ãããŸãã ãããã説æåã§äžŠã¹æ¿ããå Žåã¯ã©ãã§ããããïŒ ãããè¡ãã«ã¯ã説æåã«ã€ã³ããã¯ã¹ãäœæããã¯ã©ã¹ã¿ãªã³ã°ããŠããŒãã«ãç©ççã«åæ§ç¯ããå¿
èŠããããŸãã
CREATE INDEX description_idx ON medley USING btree (description); CLUSTER medley USING description_idx;
æåã®ããŒãžãããã¹ãŠã®è¡ããã§ãããããšã説æåã§ã¢ã«ãã¡ãããé ã«ãœãŒããããããŒã¿ãè¿ãããŸãã ããŒãã«ã倿Žããããšãæ°ããè¡ã¯ã¢ã«ãã¡ãããé ã®ãªã¹ãããåé€ãããŸãããããŒãã«ã倿ŽãããŠããªãéããè¿ããããªããžã§ã¯ãã¯å®å
šãªé åºã«ãªããŸãã ããã«ããã®æäœã¯ããŒãã«ããããã¯ãããŠãŒã¶ãŒãã¢ã¯ã»ã¹ããå¿
èŠãããå Žåã¯å®è¡ã§ããªããšããäºå®ã«ããããããã倿ŽåŸã«å®æçã«åã¯ã©ã¹ã¿ãŒåã§ããŸãã
æåŸã«ããã€ãåäœã®åèšãµã€ãºã䜿çšããŠãããŒãã«ã®ããŒãžã®åèšæ°ã決å®ã§ããŸãã
SELECT pg_relation_size('medley') / current_setting('block_size')::int;
䜿çšããå ŽåïŒTIDã¹ãã£ã³ã é«éã©ã³ãã ã¢ã¯ã»ã¹ãå¿
èŠã§ããã£ã«ã¿ãªã³ã°ãäžèŠãªå Žåã å®è³ªçã«å€åããªãã©ã€ã³å¹
ã§ãå¢å ããæéããŒã¿ã®ã¿ã§ç¹ã«ããŸãæ©èœããŸãã
è©äŸ¡ã¿ãä»ãããŒã»ãã
ãããŸã§èŠãŠããããã«ãããŒã»ããã®éåžžã®ããŒãžããŒã·ã§ã³ã§ã¯ããŠãŒã¶ãŒãæšæž¬ããå Žåãé€ããç¹å®ã®ããŒãžã«ç§»åã§ããŸããã ãã ããPostgreSQLçµ±èšæ
å ±ã³ã¬ã¯ã¿ãŒã¯åååžãã¹ãã°ã©ã ããµããŒãããŸãã ãããã®æšå®å€ãå¶éãšå°ããªãªãã»ãããšçµã¿åãããŠäœ¿çšââããŠããã€ããªããã¢ãããŒãã«ããé«éã©ã³ãã ã¢ã¯ã»ã¹ã®ããŒãžããŒã·ã§ã³ãååŸã§ããŸãã
æåã«ããã®äŸã®çµ±èšãèŠãŠã¿ãŸãããã
SELECT array_length(histogram_bounds, 1) - 1 FROM pg_stats WHERE tablename = 'medley' AND attname = 'n';
ç§ã®ããŒã¿ããŒã¹ã§ã¯ãånã«ã¯101ã®å¢çææ°ããããŸãã ãããã®éã®100ã®ç¯å²ã ããŒã¿ãåçã«åæ£ãããŠãããããç¹å®ã®å€ã¯æ··éããŠããŸããã
{719,103188,193973,288794, ⊠,9690475,9791775,9905770,9999847}
æ°å€ã¯æŠç®ã§ãã æåã®æ°åã¯æ£ç¢ºã«0ã§ã¯ãªããæåŸã®æ°åã¯æ£ç¢ºã«1,000äžã§ã¯ãããŸããã ç¯å²ã¯ãæ
å ±ããµã€ãºB = 10,000,000 / 100 = 100,000è¡ã®ãããã¯ã«åå²ããŸãã
PostgreSQLçµ±èšã³ã¬ã¯ã¿ã®ãã¹ãã°ã©ã ç¯å²ã䜿çšããŠã確ççã«æ£ããããŒãžãååŸã§ããŸãã ã¯ã©ã€ã¢ã³ãåŽã§WãšçããããŒãžãµã€ãºãéžæããå Žåãiçªç®ã®ããŒãžãååŸããã«ã¯ã©ãããã°ããã§ããïŒ ãããã¯IW / Bã«ããããªãã»ããIWïŒ
Bãæã¡ãŸãã
W = 20ãéžæããŠããã¹ããã¿ãŒã³ãã270,000ããŒãžãèŠæ±ããŸãããã
WITH bookmark AS ( SELECT (histogram_bounds::text::int[])[((270000 * 20) / 100000)+1] AS start, (histogram_bounds::text::int[])[((270000 * 20) / 100000)+2] AS stop FROM pg_stats WHERE tablename = 'medley' AND attname = 'n' LIMIT 1 ) SELECT * FROM medley WHERE n >= (select start from bookmark) AND n < (select stop from bookmark) ORDER BY n ASC LIMIT 20 OFFSET ((270000 * 20) % 100000);
ããã¯è¶
é«éã§ãïŒãã®å Žåãã·ããã¯ãŒãã«è¿ãæéã§çºçããããšã«æ³šæããŠãã ããïŒã ã¯ãšãªã¯ãn = 5407259ãã5407278ã®è¡ãè¿ããŸããããŒãž270,000ã®çã®å€ã¯ãn = 5400001ãã5400020ã«çãããªããŸãããã¹ã¯7239ãã€ãŸãçŽ0.1ïŒ
ã§ãã
ãã®å Žåã®ããŒãžã®éžæã¯å¹žéã§ããã 察ç
§çã«ã74999ããŒãžã«ã¯99980ã®ãªãã»ãããå¿
èŠã§ãããªãã»ããã¯100,000ãè¶
ããªãããšãããã£ãŠããŸãã劥åãããå Žåã¯ãäžéãå¶åŸ¡ã§ããŸãã PostgreSQLçµ±èšæ
å ±ã³ã¬ã¯ã¿ãŒãèšå®ããããšã«ãããããæ£ç¢ºãªåãã¹ãã°ã©ã ãååŸã§ããŸãã
ALTER TABLE medley ALTER COLUMN n SET statistics 1000; VACUUM ANALYZE;
ããã§ã100åã®ãã¹ãã°ã©ã å€ã§ã¯ãªãã1000åã«ãªããŸããã ç§ã®ããŒã¿ããŒã¹ã§ã¯ã次ã®ããã«ãªã£ãŠããŸãã
{10,10230,20863, âŠ, 9980444,9989948,9999995}
åæã«ãã·ããã®ã¹ãããã¯10000以äžã«ãªããŸãããã¬ãŒããªãã¯ãã¹ã±ãžã¥ãŒã©ãããå€ãã®å€ãã¹ãã£ã³ããããã«ãªããŸãããé床ãäœäžããããšã§ãã ãããã£ãŠãããã¯ãã€ã¢ã¹ã®éå¹çæ§ãšçµ±èšæ
å ±ã³ã¬ã¯ã¿ã®ãªãŒããŒãããã®äº€å·®ç¹ã§ãã
ãã®ãã€ããªãããªãããŒã»ãã/ãªãã»ãããæ¹åŒã¯ãããããå€ãã®å®éã®ããŒãžããŒã·ã§ã³ã¢ããªã±ãŒã·ã§ã³ã«ã¯é©ããŠããŸããã ãããŠãããã§ã¯ãã©ããæ¡ä»¶ã¯æ©èœããŸããã ããã«ãããŒãã«ã倿Žãããšããããã³çµ±èšã³ã¬ã¯ã¿ãŒãé·æéèµ·åãããŠããªãå Žåãäžæ£ç¢ºã§ããããŸããŸãäžæ£ç¢ºã«ãªããŸãã
䜿çšããå ŽåïŒè©äŸ¡ããã¯ããŒã¯ä»ãã®ããŒã®ã»ããã ãŠãŒã¶ãŒã远å ã®ãã£ã«ã¿ãªã³ã°ãªãã§ãæ·±ãããããããã®ã©ã³ãã ã¢ã¯ã»ã¹ãå¿
èŠãšããå Žåã
çµè«
ä»ã®å€ãã®ãšã³ãžãã¢ãªã³ã°ãœãªã¥ãŒã·ã§ã³ãšåæ§ã«ãããŒãžããŒã·ã§ã³æè¡ãéžæããã«ã¯åŠ¥åãå¿
èŠã§ãã ããŒã»ããã®ããŒãžããŒã·ã§ã³ã¯ãç·åœ¢ã¢ã¯ã»ã¹ãé åºä»ããããäžèŠæš¡ãµã€ãã«æãé©ããŠãããšç¢ºä¿¡ã§ããŸãã ãã ããå¶é/ãªãã»ããæ¹åŒã«ãç¬èªã®é·æãããããããšããŸããã¯ãªæ¹åŒã¯ç¹å®ã®ã¿ã€ãã®ããŒã¿ã«å¯ŸããŠç¹å¥ãªããã©ãŒãã³ã¹ç¹æ§ãæäŸããŸãã ã芧ã®ãšãããããªãã®æ°ã®å¯èœæ§ããããŸãã ãžã§ãã«é©ããããŒã«ãéžæããããŒãžããŒã·ã§ã³ãéããæ¬ã«ããªãã§ãã ããã