Doctrineã¨Propelã®ããã©ã¼ãã³ã¹æ¯è¼
# 2009/09/23 22:45 Fivestarããããã³ã¡ã³ãã§æãã¦ããã ããDoctrineã®INSERTã«ã¤ãã¦ãã¹ã1ã«è¿½è¨ãã¾ããã
# 2009/09/24 01:03 Fivestarããããã³ã¡ã³ãã§æãã¦ããã ããDoctrineã®QueryCacheã«ã¤ãã¦ãã¹ã3ã«è¿½è¨ãã¾ããã
symfonyã¨ãã¦ã¯ãããããã¯Doctrineãã¡ã¤ã³ãã¨ããæ¹åæ§ï¼symfony 1.3ã§ã¯ããã©ã«ãã®ORMãDoctrineã«ãªã£ã¦ãã¾ããï¼ã®ãããªã®ã§ããããããªæ©è½ãDoctrineãåºæºã«å®è£ ããã¦ãããã¨ã«ãªãã®ã ããã¨æããã¾ãããå®éã®æ¡ä»¶ã«ä½¿ã£ã¦ããã«ã¯ããã¯ãããã©ã¼ãã³ã¹ãæ°ã«ãªãã¨ããã§ãã
ããããPropelã§ãPDOãæ¡ç¨ããã1.3ãåºãã¾ã§ã¯ãããããé ããã¨è¨ããã¦ãã¦ãããããsymfonyã£ã¦ãã£ãããã®åå ã«ãªã£ã¦ããã®ã§ã¯ãªããã¨å人çã«æã£ã¦ããããã¾ããã¯ã¨ãªã®æ¸ãæ¹ãã©ã¤ãã©ãªã®æ§é çã«ã¯Doctrineã®æ¹ãå é²çãªã®ã¯ç¢ºããªã®ã§ãããå°ãªãã¨ãPropel 1.3ã¨æ¯è¼ãã¦ãæ°ã«ãªããªããç¨åº¦ã®é度ãåºã¦ããã®ãã©ãããèªåã§ç¢ºèªãã¦ã¿ã¾ããã
以ä¸ã®ãããªç°¡åãªå¦çã«ã¤ãã¦ãæéãè¨æ¸¬ãã¦ãã¾ãã
- 10000件ã®ã¬ã³ã¼ããINSERT
- 10000件ã®ã¬ã³ã¼ããããã©ã¤ããªãã¼ã§ã©ã³ãã ã«1件ãåå¾ããå¦çã10000å
使ç¨ãããã¼ã¸ã§ã³ãç°å¢å¤æ°ãªã©ã¯ä»¥ä¸ã®éãã§ãã
- symfony 1.3.0-DEV
- Doctrine 1.2.0-ALPHA1(symfony 1.3ã«ä»å±ã®ãã®)
- Propel 1.3.0-DEV(symfony 1.3ã«ä»å±ã®ãã®)
- PHP 5.2.6
- memory_limit 32M
- ãã¼ãã«ãaddressããåç´ãªä½æãæ ¼ç´ããããã®ãã¼ãã«ããªã¬ã¼ã·ã§ã³çãªããautoincrementã®ä¸»ãã¼ã®ã¿ã
ã¾ãã以ä¸ã®ããã«Propelã¨Doctrineã®ããã¸ã§ã¯ããä½æãã¦ãã¾ãã
- symfony 1.3ãã©ã³ããsvnãããã§ãã¯ã¢ã¦ããããã®ã©ã¤ãã©ãªã使ç¨ãã¦Doctrineã®ããã¸ã§ã¯ããä½æãã
- Doctrineã®ããã¸ã§ã¯ãã§schema.ymlãè¨å®âãã¼ã¿ãã¼ã¹ã«ãã¼ãã«ãçæ
- åãã©ã¤ãã©ãªã使ç¨ãã¦ãPropelã®ããã¸ã§ã¯ããä½æãã
- ãã¼ã¿ãã¼ã¹ããã¹ãã¼ããçæï¼symfony propel:build-schemaï¼ããã¹ãã¼ãããã¢ãã«ãçæï¼symfony propel:build-modelï¼
ãã¹ã1ï¼10000ã¬ã³ã¼ãINSERT
Doctrine/Propelã®ããã¸ã§ã¯ãã§ããããã¿ã¹ã¯ãä½æãã1ä¸ä»¶ã®ã¬ã³ã¼ããORMã使ã£ã¦INSERTãã¾ããåç´ãªä»¥ä¸ã®ãããªã³ã¼ããæ¸ãã¾ããã
ãDoctrine/Propelå ±éã
<?php for($i=0; $i<10000;++$i){ echo $i . "\n"; $address = new Address(); $address->setZip1('111'); $address->setZip2('2222'); $address->setPrefName('å²éç'); $address->setAddr1('ãããããããããããããããããããã'); $address->save(); unset($address); }
ãã®ã¿ã¹ã¯ãå®è¡ããçµæã¯ä»¥ä¸ã®éãã§ãã
Doctrine | Doctrine ï¼freeããï¼ |
Doctrine ï¼Doctrine_Connection#insertï¼ |
Propel |
---|---|---|---|
4698件ã¾ã§ã§ã¡ã¢ãªã¢ãã±ã¼ã·ã§ã³ã¨ã©ã¼ | 46ç§ç¨åº¦ã§å®äº | 12ç§ç¨åº¦ã§å®äº | 27ç§ç¨åº¦ã§å®äº |
ãªããDoctrineã®å ´åã¯ã¡ã¢ãªã使ãåã£ã¦ãã¾ã£ã¦ã¨ã©ã¼ã«ãªã£ã¦ãã¾ãã¾ããã
ããã«ã¤ãã¦Doctrineã®ããã¥ã¢ã«ã調ã¹ãã¨ãããæ示çã«free()ã¡ã½ãããå¼ã³åºãå¿
è¦ãããããã§ãã
ãããã£ã¦ã以ä¸ã®ããã«ã³ã¼ããæ¸ãæããã¨ãããç¡äº10000件ã®ã¬ã³ã¼ãã追å ã§ãã¾ããã
ãDoctrineã
<?php for($i=0; $i<10000;++$i){ echo $i . "\n"; $address = new Address(); $address->setZip1('111'); $address->setZip2('2222'); $address->setPrefName('å²éç'); $address->setAddr1('ãããããããããããããããããããã'); $address->save(); $address->free(true); // â æ示çã«è§£æ¾ unset($address); }
追è¨1ï¼ã³ã¡ã³ãæ¬ã«ã¦id:Fivestarããããæãã¦ããã ããDoctrine_Connection#insertã¡ã½ããã使ç¨ããæ¹æ³ã試ãã¾ãããï¼çµæã¯ä¸ã®è¡¨ã«è¿½å ï¼ã³ã¼ãã¯ä»¥ä¸ã®éãã§ãã
ãDoctrine(Doctrine_Connection#insert)ã
<?php $table = Doctrine::getTable('Address'); $conn = $table->getConnection(); for($i=0; $i<10000;++$i){ $conn->insert($table,array( 'zip1'=>'111', 'zip2'=>'2222', 'pref_name'=>'å²éç', 'addr1'=>'ãããããããããããããããããããã', 'addr2'=>'', 'addr3'=>'', 'created_at'=>date('Y/m/d H:i:s'), 'updated_at'=>date('Y/m/d H:i:s'), )); }
å
容ã¨ãã¦ã¯ãã¾ãã«ã¼ãã®å¤ã§å¯¾è±¡ãã¼ãã«ã®ã¤ã³ã¹ã¿ã³ã¹ã¨Doctrine_Connectionã®åç
§ãåå¾ãã¦ãããã«ã¼ãå
ã§ã¯Doctrine_Connection#insertã¡ã½ããã使ç¨ãã¦ã¬ã³ã¼ãã追å ãã¾ãã
注æãå¿
è¦ãªã®ã¯ãDoctrine_Connection#insertã使ã£ãå¦çã§ã¯ORMãï¼ã»ã¨ãã©ï¼çµç±ããã«ãPDOã§INSERTã¯ã¨ãªãæããã¨ããç¹ã§ããã§ãã®ã§ãä¸è¨ã³ã¼ãã®ããã«created_atãupdated_atãªã©ã®ãã£ã¼ã«ãã®å¤ãèªåã§è¨å®ããå¿
è¦ãããã¾ãã
ããã¾ã§æ¥ãã¨ãã»ã¼PDOã§ç´ã«æ¸ãã¦ããã®ã¨åããããã®é度ãåºã¦ãã¾ããããã ã£ããPDOã§çã§æ¸ãã°ããããããã¨è¨ããããã§ãããDoctrine_Connection#insertã®æ¹ããæ¸ãæ¹ã¯æ¥½ãªããã«ç§ã¯æãã¾ãã
ã¨ããããã§ããã®é¨åã®çµè«ã¨ãã¦ã¯ããDoctrineã§å¤§éã«INSERTããå ´åã¯Doctrine_Connection#insertã使ãã¹ããã¨ãããã¨ã§ããããã
Fivestarãããããã¨ããããã¾ããã
ãã¹ã2ï¼10000å主ãã¼ã§ã¬ã³ã¼ãåå¾
次ã«ããã¹ã1ã§æ¿å ¥ãã10000件ã®ã¬ã³ã¼ããããã©ã³ãã ã«ä¸»ãã¼ãæå®ãã¦1件ãåå¾ããæä½ã10000åç¹°ãè¿ãã¨ããã³ã¼ããæ¸ãã¦ã¿ã¾ããã
ãDoctrineã
<?php for($i=0; $i<10000;++$i){ $rec = Doctrine::getTable('Address')->find((int)rand(1,10000)); unset($rec); }
ãPropelã
<?php for($i=0; $i<10000;++$i){ $rec = AddressPeer::retrieveByPk((int)rand(1,10000)); unset($rec); }
ãã®ã³ã¼ãã®å®è¡çµæã¯ä»¥ä¸ã®ããã«ãªãã¾ããã
ã | Doctrine | Propel | Propel ï¼InstancePoolingç¡å¹ï¼ |
---|---|---|---|
1åç® | 46.4ç§ | 7.5ç§ | 11.1ç§ |
2åç® | 46.6ç§ | 7.8ç§ | 11.4ç§ |
Doctrineã§ãPropelã§ããä¸è¨ã³ã¼ãã§ä½¿ã£ã主ãã¼ããç°¡åã«ã¬ã³ã¼ããåå¾ããã¡ã½ããã¯ãããããã®ç´æ¥ã¯ã¨ãªãçµã¿ç«ã¦ãæ¹æ³ãå
é¨ã§ä½¿ã£ã¦ããç¹ã¯åãã§ãã
ãã ããPropelã§ã¯InstancePoolingã¨ããæ©è½ãããã©ã«ãã§æå¹ã«ãªã£ã¦ãã¾ãï¼Propel 1.3ããã®æ©è½ï¼ãå
·ä½çã«ã¯ãã¢ãã«ã¯ã©ã¹ã®populateObjectsã¡ã½ããå
ã§ãç¹å®ã®ä¸»ãã¼ã«å¯¾å¿ãããªãã¸ã§ã¯ãããã£ãã·ã¥ï¼é£æ³é
åï¼ã«ä¿åããã次åã®retrieveByPkå¼ã³åºãã®éã«é£æ³é
åãããªãã¸ã§ã¯ããè¿ããã¾ãã
ä¸è¨ã®è¨æ¸¬çµæã§ã¯ãInstancePoolingã®å¹æã*ããç¨åº¦*å¹ããããã«éããªã£ã¦ããããã§ãã
試ãã«InstancePoolingãç¡å¹ã«ãã¦è¨æ¸¬ããã®ãä¸çªå³ã®åã®æ°å¤ã§ããInstancePoolingãç¡å¹ã«ããã«ã¯ã以ä¸ã®ããã«ãã¾ãã
<?php Propel::disableInstancePooling();
Propelã§InstancePoolingãç¡å¹ã«ãã¦ããDoctrineã«å¯¾ãã¦ç´1/4ã®å®è¡æéã§ãã
Hydrationããªãã§æ¯è¼
ãDoctrineã¯Hydrationãé
ããããã¨ãã声ãã©ããããèããã¦æ¥ãã®ã§ãHydrationãããªãããã«ãã¦æ¯è¼ãã¦ã¿ã¾ããã
â»Hydrationã¨ã¯ããã¼ã¿ãã¼ã¹ããåå¾ããã¬ã³ã¼ãã«å¯¾å¿ãããªãã¸ã§ã¯ããçæãããã®ãªãã¸ã§ã¯ãã«ã¬ã³ã¼ãã®ãã¼ã¿ãè¨å®ããå¦çã®ãã¨ã§ãã
ãDoctrineã
<?php for($i=0; $i<10000;++$i){ $q = Doctrine_Query::create()->from('Address a')->where('id = ?', (int)rand(1,10000))->limit(1); $rec = $q->execute(array(), Doctrine::HYDRATE_NONE); $q->free(); unset($rec,$q); }
ãPropelã
<?php for($i=0; $i<10000;++$i){ $c = new Criteria(); $c->addSelectColumn(AddressPeer::ID); $c->addSelectColumn(AddressPeer::ZIP1); $c->addSelectColumn(AddressPeer::ZIP2); $c->addSelectColumn(AddressPeer::PREF_NAME); $c->addSelectColumn(AddressPeer::ADDR1); $c->addSelectColumn(AddressPeer::ADDR2); $c->addSelectColumn(AddressPeer::ADDR3); $c->setPrimaryTableName(AddressPeer::TABLE_NAME); $c->add(AddressPeer::ID, (int)rand(1,10000)); $c->setLimit(1); $stmt = BasePeer::doSelect($c); $stmt->fetch(PDO::FETCH_ASSOC); unset($stmt); unset($c); }
Doctrineã§ã¯ãexecute()ã®ãªãã·ã§ã³ã«Doctrine::HYDRATE_NONEãæå®ããã¨ãç´æ¥é
åãè¿ããã¾ãã
åæ§ã«Propelã§ã¯BasePeerã®doSelect()ã¡ã½ããã使ã£ã¦PDOStatementãåå¾ããçµæãé
åã§åå¾ãã¦ãã¾ãã
å®è¡çµæã¯ä»¥ä¸ã®éãã§ãã
ã | Doctrine | Doctrine (Query Cacheãã) |
Doctrine (Query Cache/Result Cacheãã) |
Propel |
---|---|---|---|---|
1åç® | 36.7ç§ | 11.0ç§ | 8.7ç§ | 9.8ç§ |
2åç® | 36.8ç§ | 11.1ç§ | 8.6ç§ | 9.9ç§ |
Doctrineã¯ãã¹ã2ã®çµæããã ãã¶éããªãã¾ãããPropelã®å ´åã¯ããã¹ã2ã§InstancePoolingãç¡å¹ã«ããå ´åããéããªã£ã¦ãã¾ãããï¼ãã¡ãããã¹ã3ã§ã¯Poolingã¯è¡ããã¾ããï¼
ãªããDoctrineã®ã³ã¼ãã§ã$q->free()ãã¨free()ã¡ã½ãããå¼ã³åºãã¦ãã¾ããããã®è¡ããªãã¨ãéä¸ã§ã¡ã¢ãªã¢ãã±ã¼ã·ã§ã³ã¨ã©ã¼ãçºçãã¦ãã¾ãã¾ãã
注ï¼ãããããã¯ã¨ãªã®åæåå¦çãã«ã¼ãã®å¤ã«åºããã¨ã§å¤å°ã®é«éåã¯ã§ãã¾ãã
追è¨1ï¼ã³ã¡ã³ãæ¬ã«ã¦id:Fivestarããããæãã¦ããã ããQuery Cacheã試ãã¦ã¿ã¾ãããï¼è¦APCï¼
APCãã¤ã³ã¹ãã¼ã«ããã¦ããªãå ´åã¯ã¤ã³ã¹ãã¼ã«ãã¦æå¹åãã以ä¸ã®ããã«ã³ã¼ããå¤æ´ãã¾ãã
ãDoctrine(Query Cacheç)ã
<?php $manager = Doctrine_Manager::getInstance(); $manager->setAttribute(Doctrine::ATTR_QUERY_CACHE, new Doctrine_Cache_Apc()); $q = Doctrine_Query::create()->from('Address a')->where('id = :id'); for($i=0; $i<10000;++$i){ $rec = $q->fetchOne(array(':id'=>(int)rand(1,10000)), Doctrine::HYDRATE_NONE); unset($rec); }
Doctrineã®Query Cacheãæåã«æå¹åãã¦ãã¾ããã¾ããæé©åã®ããã«ã¯ã¨ãªã®å ±éé¨åãã«ã¼ãã®å¤ã«åºãã¾ãããããã§ããªãPropelã®é度ã«è¿ã¥ãã¦ãã¾ãã
ãã ããPropelå´ã¯ãããã£ããã£ãã·ã¥ã¯ä½¿ã£ã¦ãã¾ãããPropelã§ã¯doSelectã®å¼ã³åºãæç¹ã§ã¯ã¨ãªãçµã¿ç«ã¦ããã¾ãã®ã§ããã®çµã¿ç«ã¦å¦çã®çµæãåæ§ã«APCã«ãã¾ããã£ãã·ã¥ãã¦ããã°ç¸å½é«éåã§ããã®ããããã¾ããããã ãPropelã«ã¯ã¯ã¨ãªãçµã¿ç«ã¦ãåã«ãã©ããã£ãã¯ã¨ãªãªã®ããã¨ããæ å ±ï¼= APCã«ä¿åããããã®ãã¼ã¨ãªãï¼ããªããããä¸æãå®ç¾ã§ãããã©ããã¯åããã¾ãããDoctrineã®å ´åã¯DQLãããã·ã¥åããæååããã¼ã¨ãã¦ä½¿ããã¦ãã¾ãã
ããã«Result Cacheãã»ã¼åæ§ã®è¨å®ã§æå¹åã§ãã¾ãã試ããã¨ãããPropelã®InstancePoolingã¨åç¨åº¦ã«é«éåãã¾ããï¼è¡¨ã®3åç®ï¼ããã¡ãã®å ´åã¯Propelã®InstancePoolingã¨ã¯ç°ãªããAPCã§ãã£ãã·ã¥ãã¦ããã®ã§ããªã¯ã¨ã¹ããã¾ããã§ã®å¹æãæå¾ ã§ãã¾ãã
ããã§ã®çµè«ã¨ãã¦ã¯ãDoctrineã使ãå ´åã¯APCã¨Query Cacheãæå¹åãã¹ããã¨ãããã¨ã§ããããã
ã³ã¡ã³ãããã ããFivestarããããããã¨ããããã¾ãï¼
注ï¼ãã®ãã¹ãã¯CLIã§è¡ã£ã¦ãã¾ãããCLIã§APCãæå¹ã«ããã«ã¯ããapc.enable_cli=1ãã«è¨å®ããªãã¨ããã¾ãããï¼ããã§ãã°ããããã£ã¦ã¾ããï¼
çµè«
ç§ã¯ã¾ã ã¾ã Doctrineã«ã¤ãã¦ã®çµé¨ãæµ ãã®ã§ããã£ã¨å¹æçãªæ¸ãæ¹ã常å¥æ段ã«ããé«éåã»æé©åææ³ãããã®ããããã¾ããï¼è¿½è¨ããéããããã¤ãã®æ¹æ³ã§ããããé«éåã§ãã¾ãï¼ãããå°ãªãã¨ãæ¨æºã®ç¶æ ã§ã¯Propel 1.3ã«å¯¾ãã¦ããã©ã¼ãã³ã¹çã«ããªãè¦å£ããã¦ãã¾ãã¾ãã
ãããä¸ã§è¦ãããæè¦ã¨ãã¦ã¯ããããã³ãã¨ã³ãã¯ã©ããORMãªãã使ããªããããã¨ããæè¦ãããã¾ããã確ãã«ã¬ã¹ãã³ã¹æ§è½ãªã©ãç¹ã«æ±ããããç®æã§ã¯ãç´æ¥PDOã使ç¨ããããå¾ã¾ããã
ãªã®ã§ããã¬ã¹ãã³ã¹æ§è½ã¯ãã»ã©éè¦ã§ã¯ãªããç®æã§ORMã使ã£ã¦éçºå¹çãä¸ããã¨ãããã¨ã«ãªãã®ã§ããããã©ããããã£ãå¦çã»ç»é¢ã§ããã許容ã§ããå¿çæéãã¨ããã®ãããã¾ããããã¾ãã塵ãç©ããã°ã¨ãããã¨ã§ãç´°ããªå¦çã§ãããããè¡ãå¿ è¦ãããå ´åã¯ãã許容ã§ããå¿çæéãå ã«è©°ãè¾¼ããå¦çã®éã«å½±é¿ãã¦ãã¾ãã¾ãã
Doctrineã¯ç¢ºãã«å é²æ§ã®ããã©ã¤ãã©ãªã§ãæ¸ãæ¹ãSQLã«è¿ããããPropelã¨æ¯è¼ãã¦å¦ç¿ã³ã¹ããå°ãªãã¦æ¸ãã®ããããã¾ãããããããç§å人ã¨ãã¦ã¯ãå°ãªãã¨ãPropelã¨åç¨åº¦ã®å¿çæ§è½ãåºãããã«ãªãã¾ã§ã¯ãå®éã®æ¡ä»¶ã§Doctrine使ç¨ããã®ã¯å¾ ã¡ãããªãã¨æãã¾ããã
[2010/01/23追è¨]
ã¨æ¸ãã¤ã¤ãã使ãè¾¼ãã§ãããã¡ã«ã ãã ãDoctrineã好ãã«ãªã£ã¦ãã¾ããã
P.S.
Doctrineã使ãè¾¼ãã§ããæ¹ããããããã°éããã¨ãããããªã¢ããã¤ã¹ãªã©ãããã°ãé¡ããã¾ãï¼
â»Doctrineã®compile()ã¨ã使ãã°ãã£ã¨éãã®ããããã¾ããã»ã»ã»
http://www.doctrine-project.org/documentation/manual/1_1/ja/improving-performance#%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB