3

400k レコードを含むInnoDbitemテーブルにクエリがあります (のみ...)。プレゼンテーション レイヤー (1 ページあたり 60) の結果をページングする必要があるため、LIMIT表示するページに応じて値を使用します。

クエリは次のとおりです (110000オフセットは単なる例です)。

SELECT i.id, sale_type, property_type, title, property_name, latitude,
       longitude,street_number, street_name, post_code,picture, url,
       score, dw_id, post_date
FROM item i WHERE picture IS NOT NULL AND picture != ''
AND sale_type = 0
ORDER BY score DESC  LIMIT 110000, 60;

私のマシンでこのクエリを実行すると、約 1 秒かかります。テスト サーバーでこのクエリを実行すると、45 ~ 50 秒かかります。

EXPLAIN はどちらも同じです:

+----+-------------+-------+-------+---------------+-----------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys | key       | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+---------------+-----------+---------+------+--------+-------------+
|  1 | SIMPLE      | i     | index | NULL          | IDX_SCORE | 5       | NULL | 110060 | Using where |
+----+-------------+-------+-------+---------------+-----------+---------+------+--------+-------------+

クエリ時の構成の唯一の違いは次のshow variablesとおりです。

  • innodb_use_native_aio. 私のマシンではなく、テストサーバーで有効になっています。無効にしてみましたが、大きな変化は見られません
  • innodb_buffer_pool_sizeテストサーバーで1G、私のマシンで2G

テスト サーバーには 2Gb の RAM、2 コア CPU があります。

  • mysqld は常に RAM の 65% を超えて使用しますが、クエリを超えると 1 ~ 2% しか増加しません
  • mysqld は、上記のクエリの実行中に CPU の 14% を使用し、アイドル状態のときは使用しません

私のローカル マシンには 8Gb、8 コアの CPU があります。

  • mysqld は常に RAM の 28% を使用し、上記のクエリを実行している間 (または私が確認できる非常に短い時間)、実際には増加しません。
  • mysqld は、上記のクエリの実行中に CPU の 48% を使用し、アイドル状態のときは使用しません

テスト サーバーで同じパフォーマンスを得るには、どこで何をすればよいですか? RAM や CPU が少なすぎませんか?

アップデート

同じ仕様の新しいテスト サーバーをセットアップしましたが、8G の RAM と 4 コアの CPU を使用すると、パフォーマンスが私のマシンと同様の値に跳ね上がりました。元のサーバーはすべての RAM/CPU を使用していないように見えましたが、パフォーマンスがこれほど悪いのはなぜですか?

4

1 に答える 1

2

パフォーマンスを低下させる最も確実な方法の 1 つは、MySQL にメモリに収まらないインデックスをスキャンさせることです。そのため、クエリ中に、インデックスの一部をバッファー プールにロードしてから、その部分を削除して、インデックスの他の部分をロードする必要があります。クエリ中にこのようにバッファー プールでチャーンが発生すると、大量の I/O 負荷が発生し、処理が非常に遅くなります。ディスク I/O は、RAM よりも約 100,000 倍遅くなります。

したがって、インデックスが 1.5GB の場合、1GB のバッファー プールと 2GB のバッファー プールの間には大きな違いがあります。

別のヒント: 本当に使いたくないLIMIT 110000, 60. これにより、MySQL はバッファー プールから 110000 行を読み取り (必要に応じてディスクからロードする可能性があります)、単にそれらを破棄します。結果セットをより効率的にページングする方法は他にもあります。

MySQL を使用した最適化されたページネーションなどの記事を参照してください。

于 2013-05-01T05:02:40.153 に答える