web-dev-qa-db-ja.com

MySQL 5.1から5.6:大きなパフォーマンスヒット

さて、これはおそらく3つの質問です。 MyISAMを使用する既存のMySQL 5.1データベースを、明らかな-そしておそらくはさらに良い-理由のホストであると私が思う理由でInnoDBを使用する5.6に移動したいと思います。

これはAmazon RDSにあるため、アップグレードルートはデータベースのダンプと再作成に限定されています。

私は、私が洗練されたDBAではないことを快く認めます。

問題1:すごい遅い!

1億6千万の奇数行をmysqldumpするのに約15分かかります。 (ショーテーブルなどが来ています、あなたの馬を握ってください。)

InnoDBに巧妙にsed-script-edされたエンジンを使用してmysql 5.6インスタンスにロードするのに50 hoursのような時間がかかりました。

問題2:私のはどこにありますか?

現在のDBでのselect count(*) from node;は、約1億6,200万ドルになります。 5.6では、それは約9300万を与えます。読み込みは成功したようですが、証明できません。少なくとも、ロードの終了後にエラーメッセージは表示されませんでした。

それが成功しなかった場合、それは本当に遅くなりました。

問題3:[〜#〜]すごい[〜#〜]遅いです!

そのため、5.1でselect count(*) from node;はほぼ瞬時に完了します-クエリ結果で0.00から0.03秒の間-。 InnoDBを使用する5.6では、1分以上かかります。説明では、これがクエリの最適化方法の違いによるものであることは明らかですが、なぜ違うのかは不明です。

テーブルと説明

MySQL 5.1

mysql> show create table node\G
*************************** 1. row ***************************
       Table: node
Create Table: CREATE TABLE `node` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `graph` varchar(100) CHARACTER SET latin1 DEFAULT NULL,
  `subject` varchar(200) NOT NULL,
  `predicate` varchar(200) NOT NULL,
  `object` mediumtext NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `nodeindex` (`graph`(20),`subject`(100),`predicate`(100),`object`(100)),
  KEY `ix_node_subject` (`subject`),
  KEY `ix_node_graph` (`graph`),
  KEY `ix_node_object` (`object`(255)),
  KEY `ix_node_predicate` (`predicate`),
  KEY `node_po` (`predicate`,`object`(130)),
  KEY `node_so` (`subject`,`object`(130)),
  KEY `node_sp` (`subject`,`predicate`(130)),
  FULLTEXT KEY `node_search` (`object`)
) ENGINE=MyISAM AUTO_INCREMENT=550671861 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> select count(id) from node;
+-----------+
| count(id) |
+-----------+
| 163426434 |
+-----------+
1 row in set (0.00 sec)


mysql> explain select count(id) from node;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                        |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
1 row in set (0.00 sec)

MySQL 5.6

mysql> show create table node\G
*************************** 1. row ***************************
       Table: node
Create Table: CREATE TABLE `node` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `graph` varchar(100) CHARACTER SET latin1 DEFAULT NULL,
  `subject` varchar(200) NOT NULL,
  `predicate` varchar(200) NOT NULL,
  `object` mediumtext NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `nodeindex` (`graph`(20),`subject`(100),`predicate`(100),`object`(100)),
  KEY `ix_node_subject` (`subject`),
  KEY `ix_node_graph` (`graph`),
  KEY `ix_node_object` (`object`(255)),
  KEY `ix_node_predicate` (`predicate`),
  KEY `node_po` (`predicate`,`object`(130)),
  KEY `node_so` (`subject`,`object`(130)),
  KEY `node_sp` (`subject`,`predicate`(130)),
  FULLTEXT KEY `node_search` (`object`)
) ENGINE=InnoDB AUTO_INCREMENT=481239575 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

「」

mysql> explain select count(id) from node;
+----+-------------+-------+-------+---------------+---------------+---------+------+----------+-------------+
| id | select_type | table | type  | possible_keys | key           | key_len | ref  | rows     | Extra       |
+----+-------------+-------+-------+---------------+---------------+---------+------+----------+-------------+
|  1 | SIMPLE      | node  | index | NULL          | ix_node_graph | 103     | NULL | 79671827 | Using index |
+----+-------------+-------+-------+---------------+---------------+---------+------+----------+-------------+
1 row in set (0.00 sec)
7
Charlie Martin

MySQLのバージョンに起因する問題はありません。これはストレージエンジンに関係しています。

問題#1への回答:すごく遅い!

Mysqldumpを実行すると、MyISAMテーブルの_.MYD_ファイルのデータのみが処理されます。したがって、15分間で1億6,300万行をダンプすることに驚くようなことはありません。

50時間かけてAmazon RDSにデータをロードしても、私にはショックはありません。どうして ?

MySQL RDSに選択したサーバーモデルに関係なく、InnoDBトランザクションログ(ib_logfile0、ib_logfile1)は常に128Mであり、 RDS CLI 。私はこれについて前に書いた: ローカルデータベースvs Amazon RDS

InnoDBへのすべての書き込みは二重書き込みバッファーに書き込まれます>ロードする前にそれを無効にする必要があります。私の投稿を参照してください InnoDBのINSERTとUPDATEを高速化する可能性

各INSERTからの行の各チャンクは、ibdata1の二重書き込みバッファとトランザクションログを介して書き込まれるものでトランザクションとして処理されます。したがって、遅さ。

問題#2への回答:行はどこにありますか?

nodeindexを見てください。プレフィックスインデックスであることがわかります。

_CREATE INDEX_の MySQLドキュメントによると

プレフィックスのサポートとプレフィックスの長さ(サポートされている場合)は、ストレージエンジンに依存します。たとえば、プレフィックスはMyISAMテーブルの場合は最大1000バイト、InnoDBテーブルの場合は767バイトにすることができます。

_graph,subject,predicate,object_の長さが767を超える行がInnoDBテーブルに入らなかったことをほぼ保証できます。

問題#3への回答:すごい遅い!

これは、ストレージエンジンが原因です。

MyISAMに対してselect count(id) from node;を実行すると、MyISAMはチートして_.MYD_ヘッダーに到達し、行数を取得します。したがって、行数を取得するための実行時間は、実際の行数の関数ではありません。これは、MySQL Query Optimizerがすべての標準メカニズムを最適化し、行数を提供する方法です。

InnoDBに関しては、行数を格納しないため、毎回テーブルを完全にスキャンする必要があります:投稿を参照してください InnoDBが行数を格納しないのはなぜですか?

提案

InnoDBとしてインポートしません。最初にMyISAMをインポートします。次に、すべてのMyISAMテーブルをInnoDBに変換します。変換する前に、nodeindexを変更するか、完全に削除する必要がある場合があります。そうしないと、変換時に行が失われます。

私の投稿を見てください 最初にmysqlバージョンをアップグレードするか、ストレージエンジンを変換しますか? 詳細については。

8
RolandoMySQLDBA