MySQLでMEMORYストレージエンジンを使用しない理由は何ですか?


28

私は最近、MySQLが認識していない「メモリ」エンジンを持っていることを発見しました(私のデータベース作業の大部分は趣味のプロジェクト向けであるため、必要に応じて学習しています)。このオプションを使用すると、パフォーマンスが大幅に向上するはずなので、それに伴う欠点はあるのでしょうか。私が知っている2つは:

  1. 問題のテーブルを保持するのに十分なRAMが必要です。
  2. マシンがシャットダウンすると、テーブルは失われます。

私はAWS EC2を使用しており、必要に応じてより多くのメモリを備えたインスタンスタイプに移行できるため、#1は問題ではないと考えています。必要に応じてディスクにダンプバックすることで、#2を軽減できると思います。

他にどんな問題がありますか?メモリエンジンは、MyISAMまたはInnoDBのいずれよりもパフォーマンスが低下することはありますか?このエンジンではインデックスが異なるということを読んだと思います。これは私が心配する必要があるものですか?

回答:


27

http://dev.mysql.com/doc/refman/5.1/en/memory-storage-engine.htmlにある機能の可用性リストを見ると、2つの問題が発生する可能性があります。

  1. トランザクションまたはFKのサポートはありません。つまり、独自のコードでトランザクションの整合性と参照の整合性を管理する必要があります(これは、アプリケーションに大きく依存しますが、DBにこれを行わせるよりもはるかに効率が悪くなる可能性があります)予想される行動パターン)。
  2. テーブルレベルのロックのみ:これは、アプリケーションが同じテーブルセットに対して複数の同時ライターを必要とする場合、または読み取り操作でロックを使用して一貫したデータの読み取りを保証する場合(そのような場合はディスクベースのテーブル)現在、十分なコンテンツがRAMにキャッシュされている場合は、ロックの粒度をより細かくサポートすることでパフォーマンスが大幅に向上します。

それ以外に、十分なRAMがあると仮定すると、メモリベースのテーブルはディスクベースのテーブルよりも高速になります。サーバーインスタンスがリセットされたときに何が起こるかという問題に対処するには、ディスクにスナップショットを作成することを考慮する必要があります。これは、データを頻繁にキャプチャする必要がある場合、全体的なパフォーマンスの利点を完全に無効にする可能性がありますそのようなインスタンスのデータは、1日に1回だけバックアップを取ることができますが、ほとんどの場合、これは受け入れられません)。

代替手段は次のとおりです。

  1. ディスクベースのテーブルを使用しますが、任意の時点でそれらをすべてRAMに保持するのに十分なRAMがあることを確認します(そして、「十分なRAM」は、マシン、OS IOバッファ/キャッシュなど)
  2. 各起動時にテーブルのコンテンツ全体(すべてのデータおよびインデックスページ)をスキャンしてSELECT * FROM <table> ORDER BY <pkey fields>、各テーブルの後にSELECT <indexed fields> FROM <table> ORDER BY <index fields>インデックスごとにコンテンツをメモリにプリロードします

この方法では、すべてのデータがRAMに格納されるため、書き込み操作のI / Oパフォーマンスのみを心配する必要があります。アプリの一般的なワーキングセットがDB全体よりもはるかに小さい場合(通常、ほとんどのアプリケーションでは、ほとんどのユーザーが最新のデータのみを見ることがあります)スキャンしてメモリにプリロードし、残りをオンデマンドでディスクからロードできるようにします。


インメモリデータベースにトランザクション整合性が必要なのはなぜですか?電源が切れると、とにかくすべてが失われます。
osa 14

@osa:すべてをシリアル化するのではなく同時アクセスを許可すると仮定すると、そのために何らかの形の整合性管理が必要になります。
デビッドスピレット14

14

メモリストレージエンジンを使用しないケースがたくさんあります-InnoDBがより高速になる場合。単純なシングルスレッドテストではなく、並行性について考える必要があります。

十分な大きさのバッファプールがある場合、InnoDBは読み取り操作に対しても完全にメモリ常駐になります。データベースにはキャッシュがあります。彼らは体を温めます!

また、行レベルのロックとMVCCの値を過小評価しないでください(リーダーはライターをブロックしません)。書き込みをディスクに保持する必要がある場合、「遅い」場合があります。ただし、少なくともメモリテーブル(MVCCなし、テーブルレベルのロック)の場合のように、書き込み操作中はブロックされません。


3

記録のために。いくつかの情報を保存するために、メモリ内のMysqlテーブルをテストしました。そして、同じ情報を保存するためにPHPのAPC(APCu)をテストしました。

58000レジストリ用。(varchar +整数+日付)。

  1. テキスト形式(csv形式)の24MBの元の情報。
  2. PHPのAPCは44.7mbのRAMを使用します。
  3. Mysqlのテーブルは575mbのRAMを使用します。

テーブルには単一のインデックスしかないので、それが主な要因だとは思いません。

結論:

メモリテーブルは大量のメモリを使用するため、「大きな」テーブルのオプションではありません


2
これは単純化された答えです。MEMORYストレージエンジンは、より小さいデータタイプを使用して、BTREEをインデックスタイプとして明示的に定義し、RAMにロードするデータの量を制限することで調整できます。これは、小規模なセットには依然として有効なオプションです。また、積極的なディスクI / Oのような他の要因もあります。私の投稿dba.stackexchange.com/questions/6156/…dba.stackexchange.com/questions/2868/…を参照してください)
RolandoMySQLDBA 14年

実際、インデックスの変更をチェックし(さらに完全に削除しました)、サイズはそれほど変化しませんでした(最初からテーブルを再構築することを含む)。私見Mysqlは内部で何かを行っています。何らかの最適化や列ごとの最大サイズの割り当て(varcharなど)かもしれません。
マガラン14年

6
その理由はほぼ確実にVARCHARによるものです:"MEMORY tables use a fixed-length row-storage format. Variable-length types such as VARCHAR are stored using a fixed length." dev.mysql.com/doc/refman/5.6/en/memory-storage-engine.html事実上、VARCHAR はMEMORYエンジンでCHARになります。
マシュー1471 14

2

MEMORYベースのテーブルのその他の欠点は、同じクエリで複数回参照できないことです。少なくともその動作はv5.4まで発見されました。CTEの使用方法(v8.x以降)では、複雑な手順にmemベースの中間テーブルを使用する必要はありません。


1

MySQLおよびMariaDBのマニュアルによると、BLOBおよびCLOB(さまざまなTEXTタイプ)はMEMORYストレージではサポートされていません。私たちの目的では、これによりMEMORYストレージエンジンはほとんど役に立たなくなりました。

http://dev.mysql.com/doc/refman/5.7/en/memory-storage-engine.html

MEMORYテーブルにBLOBまたはTEXT列を含めることはできません。

https://mariadb.com/kb/en/mariadb/memory-storage-engine/

VARCHARなどの可変長タイプは、MEMORYテーブルで使用できます。BLOBまたはTEXT列は、MEMORYテーブルではサポートされていません。

データベースの一部のみをMEMORYストレージに変換しようとしたときに、ストレージエンジン間外部キーがサポートされていないことがわかりました。そのため、BLOB / CLOBを含むテーブルへの外部キー参照を持つ必要があるすべてのテーブルも、非メモリストレージタイプにある必要があります(少なくとも、これはInnoDBの子テーブルに影響します)。


1

MEMORYテーブルは、特にデータの大規模なサブセットまたは保持が重要なあらゆるものの永続的なストレージを対象とはしていません。私の経験からの最大の目的は、複雑な手順中の一時テーブルの作成および一時的なレコードの一時的なレコードを格納することです。ディスク書き込み。この目的では、ディスクI / Oがないため、これはMyISAMまたはInnoDBよりも桁違いに高速に動作できます。特定のプロシージャ内にカプセル化されたテーブルの場合、インデックス付けとリレーションはそれほど重要ではありません永続性が期待される場所。


1

前の回答に加えて。MySQL 5.7マニュアルから直接:

「メモリのパフォーマンスは、シングルスレッドの実行と更新の処理時のテーブルロックオーバーヘッドに起因する競合によって制約されます。これにより、特に書き込みを含むステートメントミックスの場合、負荷が増加するとスケーラビリティが制限されます。」

...これは非常に現実的な制限です。たとえば、複数のセッションがあり、高速のMEMORY一時テーブルを作成しようとすると、シングルスレッドが深刻なパフォーマンスのボトルネックを引き起こす可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.