ホームページ  >  記事  >  バックエンド開発  >  Mysql_PHP チュートリアルでのページング クエリに対する 2 つのソリューションの比較

Mysql_PHP チュートリアルでのページング クエリに対する 2 つのソリューションの比較

WBOY
WBOYオリジナル
2016-07-21 15:11:31844ブラウズ

mysql でページング クエリを実行するには 2 つの方法があります。1 つは COUNT(*) を使用する方法です。具体的なコードは次のとおりです。

コードをコピーします。コードは次のとおりです:
SELECT COUNT(*) FROM foo WHERE b = 1;
SELECT a FROM foo WHERE b = 1 LIMIT 100,10;


もう 1 つのオプションは SQL_CALC_FOUND_ROWS を使用することです


コードは次のとおりです: SELECT SQL_CALC _FOUND_ROWS a FROM foo WHERE b = 1 LIMIT 100, 10 ; SELECT FOUND_ROWS(); 2 番目の方法で SQL_CALC_FOUND_ROWS を呼び出した後、2 回目には WHERE ステートメントによってクエリされた行の数が FOUND_ROWS() に配置されます。 FOUND_ROWS() をクエリして行数を確認するだけです。


これら 2 つの方法の長所と短所について説明します。
まず第一に、アトミック性の観点からは、2 番目の方が最初の方法よりも明らかに優れています。 2 番目のタイプでは、クエリ ステートメントのアトミック性を確保できます。最初のタイプでは、2 つのリクエストの間で追加の操作によってテーブルが変更されると、当然ながら不正確な結果が生じます。 2 番目のタイプはそうではありません。しかし、一般的なページをページングで表示する必要がある場合、ページングの結果はそれほど正確である必要がないことが多いのは残念です。つまり、ページングによって返される合計数が 1 より大きいか小さいかは関係ありません。したがって、実際には、アトミック性はページングの焦点では​​ありません。


以下の効率を見てください。これは非常に重要であり、ページング操作はどの Web サイトでも非常に頻繁に使用され、当然クエリ量も大きくなります。どちらを使用しても、ページング操作には必然的に 2 つの SQL クエリが存在するため、2 つのクエリのパフォーマンスについては多くの比較が行われます。 SQL_CALC_FOUND_ROWS は本当に遅いですか?
http://hi.baidu.com/ Thinkinginlamp/item/b122fdaea5ba23f614329b14

SQL_CALC_FOUND_ROWS にするか、しないのか

http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/

Lao Wang の記事では、インデックスをカバーするという概念について言及しています。簡単に言えば、テーブル クエリを実行せずにクエリがインデックスに基づいた結果のみを返す方法を意味します。

詳細については、彼の他の記事を参照してください:

MySQL カバリングインデックス

http://hi.baidu.com/ Thinkinginlamp/item/1b9aaf09014acce0f45ba6d3

実験

これらの記事を組み合わせて実験を行いました:

テーブル:

コードをコピー

コードは次のとおりです:


CREATE TABLE IF NOT EXISTS `foo` (
`a` int(10) unsigned NOT NULL AUTO_INCREMENT,

`b` int( 10) unsigned NOT NULL、`c` varchar(100) NOT NULL、主キー (`a`)、KEY `bar` (`b`,`a`) ) ENGINE=MyISAM;インデックスは b と a を使用して作成されるため、select * をクエリするときはカバー インデックスは使用されません。 a を選択する場合にのみカバー インデックスが使用されます


コードをコピーします

コードは次のとおりです。


$host = '192.168.100.166';
$user = 'root';

$db = mysql_connect($host) , $user, $password) または die('DB 接続に失敗しました');
echo '================= ======== =================' . "rn" $start =
for ($i =0; $ i mysql_query("SELECT SQL_NO_CACHE COUNT(*) FROM foo WHERE b = 1");
mysql_query("SELECT SQL_NO_CACHE a FROM foo WHERE b = 1 LIMIT 100,10"); $end = microtime(true);
echo $end . "rn"

echo '================== ======== ========' . "rn";

$start =
for ($i =0; $i mysql_query("SELECT FOUND_ROWS()");
echo $end - $start ; "rn";

エコー ' ======================================== ' . "rn";

$start = microtime(true);
for ($i mysql_query("SELECT SQL_NO_CACHE COUNT(*) FROM foo = 1" );
mysql_query("SELECT SQL_NO_CACHE * FROM foo WHERE b = 1 LIMIT 100,10");
$end = microtime(true)

echo '= ======== ==============================='

$; start = microtime(true);
for ($i =0; $i mysql_query("SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS * FROM foo WHERE b = 1 LIMIT 100, 10"); FOUND_ROWS()");
}
$end = microtime(true);
echo $end - $start . "rn";


返された結果:
Mysql_PHP チュートリアルでのページング クエリに対する 2 つのソリューションの比較
は Lao Wang の記事の内容と同じです。 SQL_CALC_FOUND_ROWS の 4 番目のクエリは、カバー インデックスを使用しないだけでなく、テーブル全体のクエリも必要とします。また、COUNT(*) の 3 番目のクエリと select * はインデックスを使用し、テーブル全体のクエリを実行しません。とても大きな違い。

まとめ
追記: なお、MyISAMを使用する場合、クエリ3と4の間に大きな違いがありますが、InnoDBを使用する場合は、それほど大きな違いはありません。

そこで、データベースが InnoDB の場合でも SQL_CALC_FOUND_ROWS を使用する傾向があるという結論に達しました

結論: SQL_CALC_FOUND_ROWS と COUNT(*) のパフォーマンスは両方のカバーリングインデックスが使用されている場合に高く、後者のパフォーマンスはカバーリングインデックスが使用されていない場合に高くなります。したがって、使用する場合はこの点に注意してください。

www.bkjia.com本当http://www.bkjia.com/PHPjc/326867.html技術記事 mysql でページング クエリを実行するには 2 つの方法があります。1 つは COUNT(*) を使用する方法です。 SELECT COUNT(*) FROM foo WHERE b = 1;ば...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。