MYSQL:SQL_CALC_FOUND_ROWSとcount(*)性能比較

5565 ワード

1.テーブルの作成:
	//         
	CREATE TABLE IF NOT EXISTS `Ben` (
	`aa` int(10) unsigned NOT NULL AUTO_INCREMENT,
	`bb` int(10) unsigned NOT NULL,
	`cc` varchar(100) NOT NULL,
	PRIMARY KEY (`aa`),
	KEY `bar` (`bb`,`aa`)
	) ENGINE=MyISAM;
	
	//     
	DROP TABLE IF EXISTS `ben`;
	CREATE TABLE IF NOT EXISTS `ben` (
	`aa` int(10) unsigned NOT NULL AUTO_INCREMENT,
	`bb` int(10) unsigned NOT NULL,
	`cc` varchar(100) NOT NULL,
	PRIMARY KEY (`aa`),
	KEY `bar` (`bb`)
	) ENGINE=MyISAM;

2.100万件のデータを挿入する:
	//    
	function insertData(){
		//      100    
		$ben = new Model();
		for($i = 0; $i < 1000000 ; $i++){
			$a = $i % 2 == 0 ? 1 : 0;
			$sql="insert into ben values (null,".$a.",'".md5($i)."')";
			$aa = $ben->query($sql);
		}
	}

3.データの読み取り、テストプログラムの実行時間:
	function read01(){
		$start = microtime(true);
		$ben = new Model();
		$ben->query("select count(*) from ben where bb=1");
		$ben->query("select aa from ben where bb=1 limit 100,10");
		$end = microtime(true);
		echo $end - $start; //    :0.018204927444458,     :0.017701148986816
	}
	function read02(){
		$start = microtime(true);
		$ben = new Model();
		$ben->query("select SQL_CALC_FOUND_ROWS aa from ben where bb=1 limit 100,10");
		$ben->query("select FOUND_ROWS()");
		$end = microtime(true);
		echo $end - $start; //    :0.017460823059082,     :0.20762395858765
	}

4.結論:
上書きインデックスを使用する場合はSQL_を使用CALC_FOUND_ROWSは性能が高い.インデックスを上書きしない場合、count(*)を使用するとパフォーマンスが向上します.またinnoDBエンジンはMyISAMよりも低い.
 
添付:
資料一:索引の上書き
select aa from ben where bb = 1;
1)統計総数:select count(*)from ben where bb=1;bbでインデックスを作成すると、このクエリは上書きインデックス(Covering Index)を使用します.
2)ページング操作:select id,title,content from ben order by createttTime desc limit 10000,10;
通常、このようなクエリはインデックスをcreatedTimeフィールド(idがプライマリ・キーである)に作成しますが、limitオフセットが大きい場合、クエリの効率は依然として低く、上書きインデックスを使用してパフォーマンスを向上させます.CREATE INDEX indexName ON ben('createTime','id')は、explainを使用して上書きインデックスであるかどうかを確認し、extra:using indexが表示されます.
 
資料二:エンジンMyISAMとInnoDBの違い
InnoDBとMyISAMは多くの人がMySQLを使用する際に最もよく使われる2つのテーブルタイプで、この2つのテーブルタイプにはそれぞれ優劣があり、具体的な応用によって異なります.基本的な違いは、MyISAMタイプではトランザクションなどの高度な処理はサポートされておらず、InnoDBタイプではサポートされていません.
MyISAMタイプのテーブルは、InnoDBタイプよりも高速で実行できるが、トランザクションサポートは提供されず、InnoDBは外部キーなどの高度なデータベース機能をサポートするパフォーマンスを強調しています.
以下に、いくつかの詳細と具体的な実装の違いを示します.
  ◆1.InnoDBではFULLTEXTタイプのインデックスはサポートされていません.
  ◆2.InnoDBにはテーブルの具体的な行数は保存されていません.つまり、select count(*)from tableを実行する場合、InnoDBはテーブル全体をスキャンして何行あるかを計算しますが、MyISAMは保存した行数を簡単に読めばいいのです.注意する
はい、count(*)文にwhere条件が含まれている場合、2つのテーブルの操作は同じです.
  ◆3.AUTO_についてINCREMENTタイプのフィールドで、InnoDBにはこのフィールドのみのインデックスが含まれている必要がありますが、MyISAMテーブルでは、他のフィールドと組み合わせてインデックスを作成できます.
  ◆4.DELETE FROM tableの場合、InnoDBはテーブルを再構築せず、1行1行削除します.
  ◆5.LOAD TABLE FROM MASTER操作はInnoDBには役に立たず、解決策はまずInnoDBテーブルをMyISAMテーブルに変更し、データをインポートしてからInnoDBテーブルに変更するが、使用する追加のInnoDB特性(例えば外部キー)のテーブルには
適用されます.
また、InnoDBテーブルのロー・ロックも絶対ではありません.SQL文を実行するときにMySQLがスキャンする範囲を特定できない場合、InnoDBテーブルはupdate table set num=1 where name like"%aa%"などのテーブル全体をロックします.
2つのタイプの最も主要な違いはInnodbがトランザクションと外部キーと行レベルロックをサポートすることである.MyISAMはサポートしていませんだからMyISAMは小さなプロジェクトでしか使えないと思われがちです.
私はMySQLを使うユーザーとして、InnodbとMyISAMはどちらも好きですが、私が現在運営しているデータベースプラットフォームから需要を達成するには:99.9%の安定性、便利な拡張性と高可用性について言えば、MyISAMは絶対に私です.
を選択して設定できます.
理由は次のとおりです.
1、まず、私が今プラットフォームに載せているプロジェクトの大部分は読み書きが少ないプロジェクトで、MyISAMの読み書き性能はInnodbよりずっと強いです.
2、MyISAMのインデックスとデータは別々で、インデックスは圧縮されており、メモリ使用率が大幅に向上しています.より多くのインデックスをロードできますが、Innodbはインデックスとデータが緊密にバンドルされており、圧縮を使用しないとInnodb比が発生します.
MyISAMは体積が大きい.
3、プラットフォームの角度から言えば、いつも1、2ヶ月ぶりにアプリケーション開発者がうっかりupdateの1つの表whereの書く範囲が間違っていて、この表が正常に使えなくなったことが発生して、この時MyISAMの優越性は体現して、勝手に当日からコピーします
ベイの圧縮パケットは対応するテーブルのファイルを取り出し、勝手にデータベースディレクトリの下に置いて、dumpをsqlにしてメインライブラリに戻り、対応するbinlogを補充します.Innodbであれば、これほど速いスピードはないかもしれません.Innodbを定期的にエクスポートするように言わないでください.
xxx.sqlメカニズムのバックアップは、私のプラットフォーム上で最小のデータベースインスタンスのデータ量が基本的に数十Gサイズであるためです.
4、私が接触した応用ロジックから言えば、select count(*)とorder byは最も頻繁で、たぶんsqlの総文全体の60%以上の操作を占めることができて、このような操作Innodbも実は表をロックすることができて、多くの人はInnodbが行級だと思っています
ロック、それはwhereがプライマリ・キーに有効であるだけで、プライマリ・キー以外のものはすべてテーブルにロックされます.
5、また、多くのアプリケーション部門が定期的にいくつかのテーブルのデータを必要としています.MyISAMの場合、そのテーブルに対応するfrmを送るだけで便利です.MYD、MYIのファイルは、対応するバージョンのデータベースで起動すればいいのですが、
Innodbはxxxをエクスポートする必要があります.sqlは、他人のファイルだけに与えるので、辞書データファイルの影響で、相手は使えません.
6、MyISAMと比較してinsert書き込み操作をすると、InnodbはMyISAMの書き込み性能に達しない.インデックスベースのupdate操作であれば、MyISAMはInnodbに劣るかもしれないが、それほど高い同時書き込みは、ライブラリから追いつけるかどうか
1つの問題は、マルチインスタンス・ライブラリ・テーブル・アーキテクチャによって解決することです.
7、MyISAMであれば、mergeエンジンはアプリケーション部門の開発速度を大幅に速めることができ、彼らはこのmergeテーブルに対してselect count(*)操作をすれば、大プロジェクトの総量が約数億のrowsのあるタイプ(ログ、調査など)に非常に適している.
統計)の業務表.
もちろんInnodbも絶対に使わないわけではありません.取引のプロジェクト、例えば株の売買プロジェクトをシミュレートします.私はInnodbを使っています.アクティブなユーザーが20万人以上いるときも、簡単に対応できます.そのため、個人的にはInnodbが好きです.ただ、データベースプラットフォームから
出発で、私はやはりMyISAMを優先します.
また、MyISAMは書き込みに耐えられないと言う人もいるかもしれませんが、アーキテクチャを通じて補うことができます.私の既存のデータベースプラットフォームの容量は、主従データの総量が数百T以上で、毎日10億以上のpvのダイナミックページがあり、いくつかの大きな項目があります.
目的は、初期memcachedが配備されていないため、単一のデータベースが毎日9千万のクエリーを処理する大きなプロジェクトを含む、pvの合計数をデータインタフェースで呼び出すことです.私のデータベース・サーバ全体の平均負荷は0.5-1程度です.
転載は出典を明記してください.ありがとうございます.