質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.90%

SQLの実行結果を計測する方法

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 847

score 2

前提・実現したいこと

MySQL(WordPress)で下記2つの関数にあるSQLどちらがいいのか計測して調べてみようと思いました。
計測はできたのですが、関数をその都度変えたいので、計測する関数 test_rate() の引数に、計測される2つの関数を渡したいです。

発生している問題・エラーメッセージ

test_rate() の引数に、計測される2つの関数を渡す方法がわかりません。(ていうか、できますか?)

該当のソースコード

まず計測される2つの関数は次の通り、test_get_var1() と test_get_var2() です。

// 「 $his_id が投稿した thread 」 への comment を取得 (var1)
function test_get_var1( $his_id ){
    global $wpdb;
    $sql = "
        SELECT    w.thing_id, w.kind_id
         FROM( 
            SELECT  base_t.thing_id    
                    ,base_t.kind_id
                    ,parent_t.user_id AS parent_thread_author_id
            FROM    wp_things base_t
                    LEFT JOIN wp_things_comment base_tc
                         ON   base_tc.comment_id=base_t.thing_id
                    LEFT JOIN wp_things parent_t
                         ON   parent_t.thing_id=base_tc.parent_thread_id AND parent_t.kind_id=2
        ) AS w    
        WHERE w.kind_id=3 AND w.parent_thread_author_id=$his_id
    ";
    $rows = $wpdb->get_results( $sql, ARRAY_A );
    return $rows;
}

// 「 $his_id が投稿した thread 」 への comment を取得 (var2)
function test_get_var2( $his_id ){
    global $wpdb;
    $sql = "
        SELECT  base_t.thing_id    
        FROM    wp_things base_t
                LEFT JOIN wp_things_comment base_tc
                     ON   base_tc.comment_id=base_t.thing_id        
        WHERE   base_tc.parent_thread_id IN (
                SELECT    parent_t.thing_id
                FROM    wp_things parent_t
                WHERE    parent_t.user_id=$his_id AND parent_t.kind_id=2
        )
    ";
    $rows = $wpdb->get_results( $sql, ARRAY_A );
    return $rows;
}


そして計測する関数は次の通り test_rate() で、以下の場合は test_get_var1() しか計測できません。

function test_rate( $lim ){
    $arr = [];
    for ($i = 0; $i < $lim; $i++){
        $time_start = microtime(true);
        $func = test_get_var1(1);
        $time = microtime(true) - $time_start;
        $arr[] = $time;
    }

    // 平均
    $sum = array_sum($arr);
    $average = $sum/count($arr);    
    return $average;
}


このように、上記の test_rate() はその関数内に test_get_var1() があるので test_get_var2() を計測するためにはこの部分を書き換えないといけません。

なので test_rate() の引数に、test_get_var1() や test_get_var2() を渡すことができればいいと考えたのですが、何かそのような方法はありますか?

試したこと

「関数 引数」で調べるとコールバック関数というのを見つけて近いのかなと思い、test_rate() で次のように文字列で関数を渡してみたのですが、実現することができませんでした。

// 計測結果を出力するために、計測される関数を文字列で渡す
echo json_encode( test_rate( 100, "test_get_var1($his_id)" ) );

// 計測を実行
function test_rate( $lim, $func_str ){
    $arr = [];
    for ($i = 0; $i < $lim; $i++){
        $time_start = microtime(true);
        func_go($func_str);
        $time = microtime(true) - $time_start;
        $arr[] = $time;
    }

    // 平均
    $sum = array_sum($arr);
    $average = $sum/count($arr);    
    return $average;
}

// 文字列で渡した関数を実行
function func_go($func_str){
    return $func_str();
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+2

アプリケーション側で実行しても画面出力やSQL本来とは関係のないロジックにより純粋な結果にはなりません。
実行予定のSQLを取得し、それぞれ実行計画をとってください。

別解

ちなみに、コマンドで実行するとちゃんと実行時間が返ってきます。
イメージ説明
※EXPLAINでもなくてもOK

なので、「アプリケーションから実行しないこと」って言ってたんですけどね。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/05/15 21:08

    DBに直接関係することはインフラ要素が強いです。
    全く知見がないのでしたら難解で当然です。
    「環境構築」と聞いて「難しそうだな」と思うのでしたらそういうレベルのことをやろうとしているという認識でいてください。
    もちろん知見が多少でもあれば考え付くことなので、あとは「どうなりたいか」で決めてください。
    先に書いたようにphpMyAdminも単なるツールです。直接DBに対して操作するほどの柔軟さはありません。

    キャンセル

  • 2020/05/15 21:18

    なるほど簡単な方法があればと思いましたが、少し手が届かなそうですね。それがわかっただけで十分です。どうも長々とお付き合いくださいましてありがとうございました。

    キャンセル

  • 2020/05/15 21:22

    はい。あとはどうなりたいかで決めてください。
    「サーバー側の検証」なので結構大変です。私も思いつく方法を挙げてはみたものの、あくまで「案」で、実証するためには段階を重ねて検証したうえでツールを1本作る必要があると思ってます。

    キャンセル

+1

WordPressでクエリの処理時間を見るだけならプラグインを入れたほうが早いと思います。

【[WP]WordPressが重い時は「Query Monitor」でクエリ実行時間などをモニターしよう | WEBデザインのTIPSまとめサイト「ウェブアンテナ」】
https://www.webantena.net/wordpress/plugin-query-monitor/

【Query Monitor – The Developer Tools Panel for WordPress】
https://querymonitor.com/

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/05/15 18:50

    JSの方法というのは「2020/05/15 18:24」に載せたJSのことです。Querymonitorで実行し、SQLの実行結果リストが100個でたものに対し、F12でコンソール画面を開き、このJSを実行して平均を求める。という方法です。

    キャンセル

  • 2020/05/15 19:16

    少なくともやってから(速度を計測して比較してから)聞きましょう。で、問題があるかどうかは自身で判断しましょう。

    キャンセル

  • 2020/05/15 20:10

    同じ処理で同じ実行時間になるならばキャッシュが効いてる場合に実行時間が異なることでわかりますが、SQLの実行時間はその都度異なるので、キャッシュが効いているかいないかわかるほどの差が出ないですね…

    まぁ…判断しましょうとのことで、あれこれとお手をわずらせてすみません。JSの方法は結局不明なのでやめて、またほかの方法で模索しておきます。

    キャンセル

0

インデックスを貼っていてもデータ量によっては使用されない場合もあります
スロークエリーが発生したり、明らかに挙動が遅い場合は
php側で測定して、対策をとればよいでしょう

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/05/15 16:14

    仰る通りphp側で測定をするコードが test_rate() で、それを動作させるための解決策を探している、というのが現状でございます。解決策について何かございましたらぜひアドバイス頂戴したく。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.90%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る