web-dev-qa-db-ja.com

InnoDBエンジンはメモリエンジンに対してスピードアップしていますか?

MySQLバージョン5.5.18のさまざまなデータベースエンジンの効率を調査して、500万行のデータセットに対する範囲クエリでの使用に最適なものを確認します。

_SELECT P.col1, P.col2, P.col3, P.col4, P.col5, P.col6, P.col7, P.col8, P.col9
 , P.col10, P.col10 * R.col3 as 'combi' 
FROM PRODUCT P INNER JOIN RATE R ON R.col2 = P.col2 
WHERE P.col3 = 'y' 
 AND P.col4 >= 1000 
 AND P.col5 >= 5 
 AND P.col6 BETWEEN 10 AND 100 
 AND P.col7 >= 0 
 AND P.col8 >= 7 
 AND P.col9 >= NOW() 
 AND P.col10 * R.col3 BETWEEN 50 AND 80
ORDER BY P.col8 DESC LIMIT 100;
_

Stackoverflowの 一部の説明 に基づいて、データベースをRAMInnoDBパラメータを設定することでロードできる可能性があることを学びました_innodb_buffer_pool_size_データセットのサイズより大きい。このパラメーターの調整後、クエリの速度がほとんどの場合MyISAMよりも速くなかったことに失望しました(平均3秒対0.3秒)およびMemoryより100倍遅い。

MySQLマニュアル をさらに検討すると、次の2つの点が述べられています。

  • InnoDBは、データとインデックスをメモリにキャッシュするためのバッファプールと呼ばれるストレージ領域を維持します。
  • バッファープールが大きくなると、より多くのInnoDBがメモリ内データベースのように機能し、ディスクからデータを一度読み取り、その後の読み取り中にメモリからデータにアクセスします。

_innodb_buffer_pool_size_は、クエリを実行するデータベースのホットコピーを提供するよりも、繰り返されたクエリの結果をキャッシュするためのもののようです。私の理解は正しいですか、それともInnoDBエンジンがメモリエンジンと一致することを可能にする何かを逃していますか?

UPDATE:

Frederick Cheungは、InnoDBバッファープールがデータベースのホットコピーをキャッシュすることを正しく指摘しました。私が見逃したのは、Rolandoからのリンクにある読み込み手順です。

各起動時にテーブルのコンテンツ全体(すべてのデータおよびインデックスページ)をスキャンして、各テーブルの_SELECT * FROM <table> ORDER BY <pkey fields>_に続いて各インデックスの_SELECT <indexed fields> FROM <table> ORDER BY <index fields>_を使用してコンテンツをメモリにプリロードします。

さらにテストすると、クエリ時間(0.3〜1.0秒)をMyISAMEngineのレベルに匹敵するレベルに下げることができます。しかし、これはMemoryエンジンで得られるものよりも約7倍遅いです。

両方のエンジンがRAMからデータベースにクエリを実行しているので、InnoDBエンジンがMemoryエンジンに対して速度を上げられない理由を誰かに教えてもらえますか?

6

皮肉なことに、先ほど InnoDBとMEMORYストレージエンジン についての質問に回答しました。

MEMORY Storage Engine について非常に奇妙な点があります。

MEMORYテーブルは、INSERT、UPDATE、およびDELETEが実行されるたびにフルテーブルロックを実行します。

MEMORYテーブルは依然として小さなディスクI/Oをトリガーします。これは、MEMORYテーブルの.frmファイルが、テーブルの存在とその後のクエリ解析の間、各クエリで参照される必要があるディスクファイルであるためです

MEMORYテーブルのデフォルトのインデックスタイプは、BTREEではなくHASHインデックスです。 USING BTREEの宣言を忘れると、すべての範囲検索がテーブルスキャンになります。 HASHインデックスは、範囲クエリを満たすインデックスの候補としては不十分です。質問の本文にあるクエリは、これによってすぐに被害を受けます。

USING BTREE句を使用してMEMORYテーブルにインデックスを作成した場合でも、RAMのBTREEインデックスはO(log n)のペースで増加するため、チェックのためにディスクI/Oを再度期待します。 .frmファイルのインデックス定義に加えて、ページアクセスのO(log n)実行時間。

MEMORYストレージエンジンを使用するときに考えるべきもう1つの奇妙なことは次のとおりです。MEMORYテーブルとInnoDBテーブルを結合しようとすると、結果として生じるロック動作はデフォルトで最悪の動作になり、この場合はフルテーブルロックになります。

警告

他の人は、2011年3月にこのような質問に答えました

全メモリデータベースの良し悪しの理由は次のとおりです: MySQLインメモリストレージエンジンで512 GBのRAMを使用することは可能ですか?

6
RolandoMySQLDBA

MySQLストレージエンジンには、トランザクションセーフテーブルを処理するものと、トランザクションセーフでないテーブルを処理するものの両方が含まれています。 MySQLは、プラグ可能なストレージエンジンアーキテクチャを通じてこれを行います。どちらにも賛否両論があります。コアの機能/パフォーマンスを4つの領域に分割できます。

  1. サポートされているフィールドとデータ型
  2. ロックタイプ
  3. インデックス作成と
  4. 取引

一部のエンジンには独自の機能があり、決定を促すこともできます。

MEMORYストレージエンジンはすべてのデータをメモリに保存します。 MySQLサーバーがシャットダウンすると、MEMORYデータベースに保存されている情報はすべて失われます。ただし、個々のテーブルのフォーマットは保持されるため、データベースサーバーを起動するたびにテーブルを再作成しなくても、情報を格納してすばやくアクセスできる一時テーブルを作成できます。

MEMORYストレージエンジンを長期間使用することは、データが非常に簡単に失われる可能性があるため、一般的には良い考えではありません。ただし、作業中のデータベースをサポートするRAMがある場合は、MEMORYベースのテーブルを使用すると、大規模なデータセットで複雑なクエリを実行し、パフォーマンスを向上させることができます。

MEMORYテーブルを使用する最良の方法は、SELECTステートメントを使用して、元のディスクベースのテーブルからより大きなデータセットを選択し、必要な特定の要素についてその情報をサブ分析することです。

InnoDBエンジンは、MyISAMエンジンのすべてのデータベース機能(およびその他)をサポートし、完全なトランザクション機能を追加します(完全なACID(原子性、整合性、分離) 、および耐久性)コンプライアンス)と行レベルのデータのロック。

InnoDBシステムの鍵は、データベースと、キャッシュとインデックスの構造であり、インデックスとデータの両方がメモリにキャッシュされるだけでなく、ディスクにも格納されます。これにより、非常に高速なリカバリが可能になり、非常に大きなデータセットでも機能します。行レベルのロックをサポートすることにより、挿入ごとにエンジンがテーブルをロックすることなく、InnoDBテーブルにデータを追加できます。これにより、データベース内の情報のリカバリと格納の両方が高速化されます。

サーバーのInnoDB設定を構成することを希望する(できる)場合は、時間をかけてサーバー構成を最適化し、InnoDBエンジンをデフォルトとして使用することをお勧めします。

詳細については、この記事を参照してください。 MySQLストレージエンジン–それらの制限と比較の試み

4
Teez