MySQLサーバーでパフォーマンスをテストしており、2 億を超えるレコードでテーブルを埋めています。ストアド プロシージャは、大きな SQL 文字列の生成に非常に時間がかかります。ヘルプやコメントは大歓迎です。
システム情報:
- データベース: MySQL 5.6.10 InnoDB データベース (テスト)。
- プロセッサー: AMD Phenom II 1090T X6 コア、各コア 3910Mhz。
- RAM: 16GB DDR3 1600Mhz CL8。
- HD: SSD に Windows 7 64 ビット SP1、SSD に mySQL をインストール、機械式ハード ディスクにログを書き込みます。
ストアド プロシージャは、テーブルに挿入されるすべての値を使用して INSERT sql クエリを作成します。
DELIMITER $$
USE `test`$$
DROP PROCEDURE IF EXISTS `inputRowsNoRandom`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `inputRowsNoRandom`(IN NumRows BIGINT)
BEGIN
/* BUILD INSERT SENTENCE WITH A LOS OF ROWS TO INSERT */
DECLARE i BIGINT;
DECLARE nMax BIGINT;
DECLARE squery LONGTEXT;
DECLARE svalues LONGTEXT;
SET i = 1;
SET nMax = NumRows + 1;
SET squery = 'INSERT INTO `entity_versionable` (fk_entity, str1, str2, bool1, double1, DATE) VALUES ';
SET svalues = '("1", "a1", 100, 1, 500000, "2013-06-14 12:40:45"),';
WHILE i < nMax DO
SET squery = CONCAT(squery, svalues);
SET i = i + 1;
END WHILE;
/*SELECT squery;*/
SET squery = LEFT(squery, CHAR_LENGTH(squery) - 1);
SET squery = CONCAT(squery, ";");
SELECT squery;
/* EXECUTE INSERT SENTENCE */
/*START TRANSACTION;*/
/*PREPARE stmt FROM squery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
*/
/*COMMIT;*/
END$$
DELIMITER ;
結果:
- 20000 個の文字列を連結すると、処理に約 45 秒かかります。
CALL test.inputRowsNoRandom(20000);
- 100000 個の文字列を連結するには、約 +5/12 分かかります O_O:
CALL test.inputRowsNoRandom(100000);
結果 (期間順) - 秒単位のステートメント期間 (合計) || フリーイングアイテム0.00005
50.00000
開始0.00002 20.00000の
実行
0.00001
10.00000の実行0.00001
10.00000
クリーンアップ0.00001 10.00000
合計0.00010100.00000
クエリ
変動値の実行によるステータス変数の変化Com_select
1 実行された SELECT ステートメントの
数 Questions 1 サーバーによって実行されたステートメントの数
テスト:
12 から 64 スレッドのさまざまな MySQL 構成で、キャッシュのオンとオフを設定し、ログを別のハードウェア ディスクに移動することを既にテストしました...
また、TEXT、INT を使用してテストしました..
追加情報:
- パフォーマンス リンク:一般 & マルチコア、構成、IO の最適化、Debiancores、最適な構成、構成48 GB RAM ..
- SQL クエリのプロファイリング: クエリのプロファイリング方法、クエリのボトルネックの可能性を確認する
質問:
- コードに何か問題がありますか?最終的な SQL 文字列を作成するために 100000 個の文字列を送信すると、結果
SELECT squery;
は NULL 文字列になります。何が起こっていますか?(エラーがあるはずですが、表示されません)。 - コードを改善して速度を上げることはできますか?
- C/Java/PHP でファイルを生成して mysql に送信する必要がありますか?
mysql -u mysqluser -p データベース名 < numbers.sql
- MySQL は1つのSQLクエリに対して1 つのコアのみを使用しているようです。(私の単一のクエリは、約 150 のスレッドで合計 CPU の 20% しか使用していないため)。
アップデート:
- 表を埋める効率的な方法については、以下のピータームの回答を確認してください。
- ストアド プロシージャ、最新の RDBMS、またはインライン クエリのパフォーマンス。