Nucleus

SQL クエリーの実行回数

2007年6月13日

globalfunctions.php にある、sql_query() 関数の冒頭部分は、次のようになっている。

function sql_query($query) {
    global $SQLCount;
    $SQLCount++;

これを用いて、何回SQLクエリーを実行したかの大まかな値を取得することが出来る。プラグインによっては、『mysql_query()』を直接呼び出しているものもあるので、実際には $SQLCount プラスαが実行回数である。

 実行回数を知るには、例えば、index.php の最後(『selector();』の次の行)に、次のように記述すると良い。

echo '<!--'.(int)$SQLCount.'/'.memory_get_usage().'-->';

ここでは同時に、メモリの消費量を見るためにmemory_get_usage()関数の戻り値も表示している(PHPのコンパイル方法によっては、この関数は使えないので注意)。

この方法を用いて、このサイトの表ページの SQL クエリーの回数を測定してみて、愕然とした。表示結果は、

<!--109/3891568-->

となり、109 回以上の SQL クエリーが実行されていることが分かった。ちなみに、同じことをインストール直後のデフォルトスキンで測定すると、11回。プラグインの追加で、実に100回も多くのクエリーを実行しているわけだ。

これは、プラグインオプションの取得部分に原因があると考えたので、PLUGIN::_getOption() 関数を次のように書き換えてみた。

function _getOption($context, $contextid, $name) {
    $oid = $this->_getOID($context, $name);
    if (!$oid) return '';


    $key = $oid . '_' . $contextid;

    if (isset($this->_aOptionValues[$key]))
        return $this->_aOptionValues[$key];
    
    $res=sql_query('SELECT o.ovalue as ovalue, o.ocontextid as ocontextid, o.oid as oid FROM '.
        sql_table('plugin_option').' as o, '.
        sql_table('plugin_option_desc').' as d'.
        ' WHERE d.opid='.(int)$this->getID().
        ' AND o.oid=d.oid');
    while($row=mysql_fetch_assoc($res)){
        $this->_aOptionValues[$row['oid'].'_'.$row['ocontextid']] = $row['ovalue'];
    }
    if (!isset($this->_aOptionValues[$key])) {
        $defVal = $this->_getDefVal($context, $name);
        $this->_aOptionValues[$key] = $defVal;
    }

    return $this->_aOptionValues[$key];
}

すべてのプラグインオプションを読み込んでメモリに入れてしまう仕様である。この方法だと結果は次のとおり。

<!--75/3894976-->

クエリーの実行を、34回減らすことが出来た。しかも、メモリ使用量はそれほど換わっていないように見える。この改変で不具合がないか、パフォーマンスがどれくらい変わったか、少し様子を見てみることにする。

ただし、プラグインによってはこの方法で半端でない量のメモリを食う可能性があるので、注意が必要だろう。

コメント

コメントはありません

コメント送信