KimuraNobu
big-m****@n-k-y*****
2008年 6月 24日 (火) 08:59:47 JST
木村と申します。 > kunitsujiです。 > > 追記です。 > ちなみにMyISAMからInnoDBにかえてみました。3000件。 > count(*)でやると、約8倍遅くなります。。 > 0.0024秒。 > SELECT FOUND_ROWS()で取得すると > 0.0003秒。 > ちなみにプライマリーキーでcount(プライマリー)としてみましたが、 > 3000件程度では変化なし。 > > アプリケーションでcount(*)をたくさん使っているものが多々ありますが、 > MyISAMからInnoDBに変えた瞬間パフォーマンス下がるということがこれでよくわ > かりますね。 > InnoDBは、クラスタインデックスだからでしょうか。 COUNT(*) だとプライマリキーが利用されると思うので、別インデックスを 指定した場合はどうなのでしょうか・・・。 >>櫻井さん。 >>>> よくあるのが、LIMITをつけて取得件数を分けてページネーションするのですが、 >>>> そのときに全体の件数をとる特にCOUNTを使いますが(MyISAMとか) >>>> num_rowの場合はSQLに対しての件数ですから、LIMITで20件だと20ですね。 >>>今回、まさにこの状況でした。 >>>ページネーションでは全体の件数がいくつか指定する必要があるので、モデルク >>>ラスに >>> ・表示させたいデータをLIMIT, OFFSET付きで取ってくる関数 >>> ・それとは別に、表示させたいデータの全ての「件数のみ」を取得する関数 >>>を書いて、コントロールクラスから呼び出すようにしました。 >>この部分ですが、上記だと2回SQLが動くことになりますよね。 >>次のようにされてみてはどうでしょう? >>MySQLということで。 >>$sql = "SELECT SQL_CALC_FOUND_ROWS " >> . "* " >> . "FROM " >> . "TABLE_NAME " >> . "WHERE " >> . "A = B " >> . "LIMIT 0, 20 " >>$result = $this->db->query($sql); >>$count = $this->db->query("SELECT FOUND_ROWS() as count"); >>として、 >>$count = $total->row(); >>var_dump($count->count); >>とすればトータル件数が取り出せますね。 >>3000件程度でベンチとりました。 >>こちらのほうが、0.0001〜0.0003早いようです(笑) >>件数が多くなればこちらのほうがいいのでしょうかね。 >>少なくともMyISAMならcount(*)は特殊な取り出ししますが、InnoDBなどの場合は >>たぶんもっと差が出るのではないでしょうか? >>_______________________________________________ >>Codeigniter-users mailing list >>Codei****@lists***** >>http://lists.sourceforge.jp/mailman/listinfo/codeigniter-users > > _______________________________________________ > Codeigniter-users mailing list > Codei****@lists***** > http://lists.sourceforge.jp/mailman/listinfo/codeigniter-users > --- 木村