PostgreSQLããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãæé©åããããšããŠããå Žåã¯ããããã
EXPLAINïŒBUFFERSãANALYZEïŒãpg_stat_statementsãauto_explainãlog_statement_min_durationãªã©ã®åºæ¬ããŒã«ã䜿çšããŸã
ãããããã
log_lock_waitsãšã®ãããã¯ã®ç«¶åãæ¢ããŠããããã¬ãŒã¯ãã€ã³ãã®åäœãç£èŠããŠããããªã©ã
ãããããããã¯ãŒã¯é
å»¶ã«ã€ããŠèããããšã¯ãããŸããïŒ ãã¬ãŒã€ãŒã¯ãããç¥ã£ãŠããŸãããããã¯ã¢ããªã±ãŒã·ã§ã³ã䜿çšãããµãŒããŒã«é¢é£ããŠããŸããïŒ
é
å»¶ã®åœ±é¿
äžè¬çãªã¯ã©ã€ã¢ã³ã/ãµãŒããŒãªã³ã°ãããã¯ãŒã¯ã®é
å»¶ã¯ã0.01ããªç§ïŒããŒã«ã«ïŒããã¹ã€ããããããã¯ãŒã¯ã§ã0.5ããªç§ãWiFiã§5ããªç§ãADSLã§20ããªç§ã倧éžéã«ãŒãã£ã³ã°ã§300ããªç§ãè¡æãWWANãªã©ã§ããã«å€åããŸããªã³ã¯ã
äºçްãª
SELECTã¯ããµãŒããŒåŽã§å®è¡ããã®ã«çŽ0.1 msããããŸãã èªæãª
æ¿å
¥ 0.5ããªç§ã
ã¢ããªã±ãŒã·ã§ã³ãèŠæ±ãå®è¡ãããã³ã«ãæå/ãšã©ãŒãå Žåã«ãã£ãŠã¯çµæãèŠæ±ã¡ã¿ããŒã¿ãªã©ãå«ããµãŒããŒããã®å¿çãåŸ
æ©ããå¿
èŠããããŸãã ããã«ã¯ããããã¯ãŒã¯äžã§å°ãªããšã1ã€ã®åŸåŸ©é
å»¶ã䌎ããŸãã
äž»ã«å°èŠæš¡ã§åçŽãªã¯ãšãªã䜿çšããå ŽåãããŒã¿ããŒã¹ãšã¢ããªã±ãŒã·ã§ã³ãç°ãªããµãŒããŒäžã«ãããšããããã¯ãŒã¯é
å»¶ãå®è¡æéã«å€§ãã圱é¿ããå¯èœæ§ããããŸãã
ã»ãšãã©ã®ã¢ããªã±ãŒã·ã§ã³ãç¹ã«ORMã¯ãéåžžã«åçŽãªã¯ãšãªã倿°å®è¡ããåŸåããããŸãã ããšãã°ãHibernateã¢ããªã±ãŒã·ã§ã³ããé
å»¶ããŠæœåºããã1000åã®åãªããžã§ã¯ããžã®@OneToManyãªã¬ãŒã·ã§ã³ãä»ããŠãšã³ãã£ãã£ãååŸããå Žåãn + 1ãã§ããã®åé¡ã«ããããããã1001ãªã¯ãšã¹ããå®è¡ããäºå®ã§ãã ããã¯ãåŸ
æ©äžã®åŸåŸ©ãã¹ã§ãããã¯ãŒã¯ãæ°ååé
å»¶ãããããšãæå³ããŸãã ãããåé¿ããããã«
å·Šçµåãã§ããã䜿çšã§ããŸããããã®åŸã芪èŠçŽ ã1000åJOINã«æž¡ããéè€æé€ããå¿
èŠããããŸãã
åæ§ã«ãORMãä»ããŠããŒã¿ããŒã¹ã«ããŒã¿ãå
¥åããå Žåãããããæ°åäžã®éåžžã®
INSERTãå®è¡ãããµãŒããŒããã®åã
ã®
INSERTã®ç¢ºèªããã¹ãŠ
å®äºããããšãåŸ
æ©ããŸãã
ã¯ãšãªã®å®è¡æéã«éäžããŠæé©åã詊ã¿ãã®ã¯ååç°¡å
ã§ãããæãåçŽãª
INSERT INTO ... VALUES ...ã§ã§ããããšã«ã¯å€æ°ã®ãªãã·ã§ã³ããã
ãŸãã ããã€ãã®ã€ã³ããã¯ã¹ãšå¶çŽãåé€ãããã©ã³ã¶ã¯ã·ã§ã³å
ã«ããããšã確èªããã°ãã»ãŒå®äºã§ãã
ãããããããã¯ãŒã¯ã®ãã¹ãŠã®æåŸ
ãåãé€ãã®ã¯ã©ãã§ããïŒ ããŒã«ã«ãããã¯ãŒã¯äžã§ãã£ãŠãã1000åã®ãªã¯ãšã¹ãã®åŸãæé·ãå§ããŸãã
ã³ããŒ
é
å»¶ãåé¿ãã1ã€ã®æ¹æ³ã¯ã
COPYã䜿çšããããšã§ãã PostgreSQlã®COPYãµããŒãã䜿çšããã«ã¯ãã¢ããªã±ãŒã·ã§ã³ãŸãã¯ãã©ã€ããŒãCSVã®ãããªæååã®ã»ãããçæããé£ç¶ããã·ãŒã±ã³ã¹ã§ãµãŒããŒã«ãããŒããã£ã¹ãããå¿
èŠããããŸãã ãŸãã¯ããµãŒããŒãã¢ããªã±ãŒã·ã§ã³ã«CSVã®ãããªã¹ããªãŒã ãéä¿¡ããããã«æ±ããããå ŽåããããŸãã
ãããã®å Žåã§ããã¢ããªã±ãŒã·ã§ã³ã¯COPYãä»ã®ã¯ãšãªãšåãæ¿ããããšã¯ã§ãããã³ããŒãšè²Œãä»ããå®å
ããŒãã«ã«çŽæ¥ããŒãããå¿
èŠããããŸãã äžè¬çãªã¢ãããŒãã¯ãCOPYãäžæããŒãã«ã«äœæãããã®ããŒãã«ãããã§ã«
INSERT INTO ... SELECT ...ãUPDATE ... FROM ....ãDELETE FROM ... USING ...ãªã©ã䜿çšããŠã 1ã€ã®æäœã§ã¡ã€ã³ããŒãã«ã倿Žããããã®ã³ããŒãããããŒã¿ã
ããã¯ãç¬èªã®SQLãçŽæ¥èšè¿°ããå Žåã«äŸ¿å©ã§ããããã¬ãŒã ã¯ãŒã¯ãšORMã¯ããããµããŒãããŠããŸãããããã«ãåçŽãªæ¿å
¥ã®ã¿ãçŽæ¥çœ®ãæããããšãã§ããŸãã ã¢ããªã±ãŒã·ã§ã³ããã¬ãŒã ã¯ãŒã¯ããŸãã¯ãŠãŒã¶ãŒãã©ã€ããŒã¯ãCOPYã«å¿
èŠãªç¹å¥ãªãã¬ãŒã³ããŒã·ã§ã³ãåŠçãããã®ããã«å¿
èŠãªã¡ã¿ããŒã¿ãæ¢ãå¿
èŠããããŸãã
ïŒCOPYãå®éã«ãµããŒãããããç¥ãããŠãããã©ã€ããŒã«ã¯ãlibpqãPgJDBCãpsycopg2ãPg gemãªã©ããããŸããããããã«åºã¥ããŠæ§ç¯ããããã¬ãŒã ã¯ãŒã¯ãšORMSãCOPYããµããŒãããå¿
èŠã¯ãããŸãããïŒ
PgJDBC-ã°ã«ãŒãåã¢ãŒã
PostgreSQLã®JDBCãã©ã€ããŒã«ã¯ããã®åé¡ã«å¯Ÿãã解決çããããŸãã JDBCãã©ã€ããŒAPIã®ã°ã«ãŒãåã®æ©èœã«åºã¥ããŠããŸãããµãŒããŒã«èŠæ±ã®ã°ã«ãŒããéä¿¡ãããã®åŸãã»ããå
šäœãæåããããšã確èªããã®ã1åã ãåŸ
æ©ããŸãã
å°ãªããšãçè«çã«ã¯ã å®éãããã€ãã®å®è£
äžã®åé¡ã«ããããã®ãã¹ãŠãäžåºŠã«ãã³ãã«ããšã«æ°çŸã®ãªã¯ãšã¹ãã«å¶éãããŸãã ãŸãããã©ã€ããŒã¯ãçµæãæéã®çµéãšãšãã«ã©ãã ã倧ãããªããã倿ã§ããå Žåã«ãçµæãã»ãããšããŠè¿ãã¯ãšãªã®ã¿ãå®è¡ã§ããŸãã ãããã®å¶éã«ããããããã
Statement.executeBatchïŒïŒã䜿çšãããšããªã¢ãŒãããŒã¿ããŒã¹ã€ã³ã¹ã¿ã³ã¹ããã®ããŒã¿ã®ãã«ã¯ããŒããªã©ã®ã¿ã¹ã¯ãå®è¡ããã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ã倧å¹
ã«åäžããŸãã
ããã¯æšæºAPIã§ãããããè€æ°ã®DBMSã§å®è¡ãããã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšã§ããŸãã ããšãã°ãHibernateã¯JDBCã°ã«ãŒãåã䜿çšã§ããŸãããããã©ã«ãã§ã¯ãããè¡ããŸããã
libpqãšã°ã«ãŒãå
ä»ã®ã»ãšãã©ã®ïŒãã¹ãŠïŒïŒPostgreSQLãã©ã€ããŒã¯ã°ã«ãŒãåããµããŒãããŠããŸããã PgJDBCã¯PostgreSQLãããã³ã«ãå®å
šã«ç¬ç«ããŠäœ¿çšããŸãããä»ã®ã»ãšãã©ã®ãã©ã€ããŒã¯PostgreSQLã®äžéšãšããŠæäŸãããC libpqã©ã€ãã©ãªã䜿çšããŸãã
libpqã«ã¯éåæã®éããããã³ã°APIããããŸããããŠãŒã¶ãŒã¯äžåºŠã«1ã€ã®ã¯ãšãªã®ã¿ãå®è¡ã§ããŸãã æ¬¡ã®ã¯ãšãªãéä¿¡ããåã«ããã®ã¯ãšãªã®çµæãåä¿¡ãããã®ãåŸ
ã€å¿
èŠããããŸãã
PostgreSQLãµãŒããŒã¯ã°ã«ãŒãåãããŸããµããŒãããŠãããPgJDBCã¯ãã§ã«ããã䜿çšããŠããŸãã ãã®ç¹ã§ã
ç§ã¯libpqã®ã°ã«ãŒãåãµããŒããäœæã ãPostgreSQLã®æ¬¡ã®ããŒãžã§ã³ã§ææ¡ããŸãã ã 確èªãããå Žåãã¯ã©ã€ã¢ã³ãã倿Žããã ããªã®ã§ãå€ããµãŒããŒã«æ¥ç¶ãããšãã®ããã»ã¹ãããã«é«éåããŸãã
èè
ããã³libpqããŒã¹ã®ãŠãŒã¶ãŒãã©ã€ããŒã®äžçŽãŠãŒã¶ãŒãšlibpqããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ã®éçºè
ããã®ãã£ãŒãããã¯ã«éåžžã«èå³ããããŸãã ãããã¯ã詊ããŠã¿ããå Žåã«PostgreSQLããŒãžã§ã³9.6ããŒã¿1ã«æ£åžžã«é©çšãããŸãã
詳现ãªããã¥ã¡ã³ããš
å
æ¬çãªãµã³ãã«ããã°ã©ã ãçšæãããŠããŸã ã
æ§èœ
RDSãŸãã¯Heroku Postgresã«åºã¥ããDBMSãµãŒããŒã¯ã説æãããŠããæ©èœãæçšãªå¥œäŸã§ãã ç¹ã«ãèªåã®ãããã¯ãŒã¯ã®å€éšãããããã«ã¢ã¯ã»ã¹ãããšãé
å»¶ãã©ã®ããã«æå·ããå¯èœæ§ãããããå®å
šã«ç€ºããŠããŸãã
ã320ããªç§ã®ãããã¯ãŒã¯é
å»¶ïŒ
- ã°ã«ãŒãåãªãã®500æ¿å
¥ïŒ167.0ç§
- ã°ã«ãŒãåã«ãã500ã®æ¿å
¥ïŒ1.2ç§
...ããã¯çŽ120åé«éã§ãã
ååãšããŠãã¢ããªã±ãŒã·ã§ã³ãé
眮ãããŠãããµãŒããŒãšããŒã¿ããŒã¹ãé
眮ãããŠãããµãŒããŒéã§å€§éžéæ¥ç¶ã䜿çšããªãã§ãã ããããããã®åããµãŒããŒã䜿çšããŠãé
å»¶ã®åœ±é¿ã瀺ããŸãã ããŒã«ã«ãã¹ãäžã®Unixãœã±ããã䜿çšããŠãã10,000åã®æ¿å
¥ã§ããã©ãŒãã³ã¹ã50ïŒ
åäžããŸããã
æ¢åã®ã¢ããªã±ãŒã·ã§ã³ã®ã°ã«ãŒãå
æ®å¿µãªãããæ¢åã®ã¢ããªã±ãŒã·ã§ã³ã®ã°ã«ãŒãåãèªåçã«æå¹ã«ããããšã¯ã§ããŸããã äžé£ã®èŠæ±ãéä¿¡ããŠããçµæãèŠæ±ããå Žåããããã«ç°ãªãã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããå¿
èŠããããŸãã
ç¹ã«ãéããããã³ã°ã¢ãŒããš
selectïŒïŒ/ pollïŒïŒ/ epollïŒïŒ/ WaitForMultipleObjectsExã«ãŒãã䜿çšããå Žåã¯ãéåælibpqã€ã³ã¿ãŒãã§ãŒã¹ãæ¢ã«äœ¿çšããŠããã¢ããªã±ãŒã·ã§ã³ãé©å¿ãããã®ã¯ç°¡å
ã§ã ã åælibpqã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããã¢ããªã±ãŒã·ã§ã³ã§ã¯ãããã«å€æŽãå¿
èŠã«ãªããŸãã
ä»ã®ã«ã¹ã¿ã ãã©ã€ããŒã®ã°ã«ãŒãå
åæ§ã«ããŠãŒã¶ãŒãã©ã€ããŒããã¬ãŒã ã¯ãŒã¯ãããã³ORMã¯éåžžãã°ã«ãŒãåãå¯èœã«ããããã«ã€ã³ã¿ãŒãã§ã€ã¹ãšå
éšå€æŽãå¿
èŠãšããŸãã æ¢ã«ã€ãã³ãã«ãŒããšãã³ããããã³ã°I / Oã䜿çšããŠããå Žåã¯ãããªãç°¡åã«å€æŽã§ããŸãã
PythonãRubyãããã³ãã®æ©èœã䜿çšã§ããä»ã®ãŠãŒã¶ãŒã«äŒããŠå¬ããã®ã§ã誰ãèå³ãæã£ãŠããããç¥ãããã§ãã ãããã§ãããšæ³åããŠãã ããïŒ
import psycopg2 conn = psycopg2.connect(...) cur = conn.cursor()
éåæã®ã°ã«ãŒãåã¯ããŠãŒã¶ãŒãè€éã«ããå¿
èŠã¯ãããŸããã
COPYã¯æéã§ã
å®çšçãªé¡§å®¢ã¯ãŸã ã³ããŒã奜ãã ããã«ç§ã®ã©ãããããããã®ããã€ãã®çµæããããŸãïŒ
inserting 1000000 rows batched, unbatched and with COPY batch insert elapsed: 23.715315s sequential insert elapsed: 36.150162s COPY elapsed: 1.743593s Done.
äœæ¥ãã°ã«ãŒãåãããšãããŒã«ã«UNIXãœã±ããã§ãé©ãã»ã©å€§ããªããã©ãŒãã³ã¹ãåäžããŸãããCOPYã§ã¯ãåã
ã®INSERTã¢ãããŒãã®äž¡æ¹ãã¯ããã«é
ããŠããŸãã
COPYã䜿çšããŸãã
ç»å
ãã®èšäºã®ç»åã¯ã西ãªãŒã¹ãã©ãªã¢ã®ããŒã¹è¿ãã®ãã³ããªã³ã°ãŠã£ã¢ãŒããå
éšïŒç æŒ ïŒã®éé±å±±ãŸã§ã®
ãŽãŒã«ããã£ãŒã«ãºçµŠæ°Žã¹ããŒã ãã€ãã©ã€ã³ã§ãã 圌女ã¯ãã®èšäºã«ã¢ãããŒãããŸãããªããªãããã®å»ºèšã®é·ããšæ¹å€ã®ããã§ããã®åµå§è
ã§ããäž»ãªåµå§è
ã§ãã
CY O'Connorã¯ããã€ãã©ã€ã³ãå§èšããã12ã¶æåã«èªæ®ºããããã§ãã å°å
ã®äººã
ã¯ããã€ãã©ã€ã³ãéãããåŸã«åœŒã亡ããªã£ããšãã°ãã°ïŒééã£ãŠïŒèšããŸãããæ°Žã¯æµããŸããã§ãã-ãã€ãã©ã€ã³ãããžã§ã¯ãã倱æã§ãããšèª°ããèããã»ã©æéãããããŸããã ããããæ°é±éåŸãæ°Žã¯è¡ããŸããã