なんか遅いZencart

ZenCart1.3.8aで運用しているサイトのパフォーマンスがなんとなく遅い。
というかかなり遅い。我慢ならんのでパフォーマンスチューニング。

とりあえずプロファイル

お約束のxdebug+WinCacheGrindで動作をプロファイリングしてみる。*1

全体の65%近い時間をinit_db_config_foreach_template_read.phpで占有されてる。
なんじゃいこりゃ。

init_db_config_foreach_template_read.php

{zenhome}/includes/init_includes/init_db_config_foreach_template_read.phpはこんなの

<?php
if (!defined('IS_ADMIN_FLAG')) {
  die('Illegal Access');
}
$template_dir = "";
$template_query = $db->Execute("select template_dir
        from " . TABLE_TEMPLATE_SELECT ." where template_language = 0");
$template_dir = $template_query->fields['template_dir'];
$template_query = $db->Execute("select template_dir from " . TABLE_TEMPLATE_SELECT . "
                                where template_language = '" . $_SESSION['languages_id'] . "'");
if ($template_query->RecordCount() > 0) {
  $template_dir = $template_query->fields['template_dir'];
}

$use_cache = (isset($_GET['nocache']) ? false : true ) ;
$configuration = $db->Execute('SELECT configuration_key AS cfgkey, configuration_value AS cfgvalue FROM '
                              .TABLE_CONFIGURATION_FOREACH_TEMPLATE.' WHERE template_dir = "'.$template_dir.'"', '', $use_cache, 150);
db_define($configuration);

$configuration = $db->Execute('SELECT DISTINCT cfg_t.configuration_key AS cfgkey,cfg_t.configuration_value AS cfgvalue 
                               FROM '.TABLE_CONFIGURATION_FOREACH_TEMPLATE.' AS cfg_ft ,'.TABLE_CONFIGURATION.' AS cfg_t 
                               WHERE cfg_ft.template_dir<>"'.$template_dir.'"');
db_define($configuration);
?>

んー。見る所dbのconfiguration_foreach_templateテーブルとconfigurationテーブルから今の設定を読み込んでdefine()しているようだ。
ってことは、この2つのテーブルに変更がない場合はキャッシュすればいいんでね?

ってことでキャッシュを利用するよう最後のクエリを変更

$configuration = $db->Execute('SELECT DISTINCT cfg_t.configuration_key AS cfgkey,cfg_t.configuration_value AS cfgvalue 
                               FROM '.TABLE_CONFIGURATION_FOREACH_TEMPLATE.' AS cfg_ft ,'.TABLE_CONFIGURATION.' AS cfg_t 
                               WHERE cfg_ft.template_dir<>"'.$template_dir.'"','',$use_cache, 86400); // 24h

だいぶ早くなったな。

注意点

configureを変更するような設定変更をした場合、次のキャッシュ更新時期まで新しい設定が読み込まれないので、明示的にキャッシュをクリアする必要がある。

キャッシュ方法としてfileを選択*2していた場合はDIR_FS_SQL_CACHEのフォルダにあるzc_*.sqlを削除。
databaseを選択している場合はデータベースのdb_cacheテーブルのレコードをクリアすればOK。

これ運用時に忘れるといらぬバグを産みかねないから、本当はconfiguration_foreach_templateテーブルとconfigurationテーブルにトリガー仕掛けてdb_cacheを削除するようにすればいいんだよなぁ。
ううむ。

*1:参考にしたのはこのへん

*2:includes/configure.php