0

私は数百万のレコードを含むテーブルを使用しており、それに対する理由を報告するためにクエリを実行する必要があります。結合のレベルなどによっては、数時間かかる場合があります。クエリを最適化する方法はたくさんあることは知っていますが、別のアプローチの可能性に興味があります。

PHP(MySQLではネイティブではない)を介して、MySQLクエリ(たとえば「SELECT * FROMテーブル」)の結果を取得し、それを配列としてMemcachedに格納してから、そのキャッシュされたバージョンに対してクエリを実行することは可能ですか?もっと速くなるでしょうか?大まかに、それはどのように機能しますか?つまり、クエリとは、次のような配列を検索することです。

Array[0] {
   Array[0] {
      'field1' => 'value1',
      'field2' => 'value2',
      'field3' => 'value3'
   },
   Array[1] {
      'field1' => 'value1',
      'field2' => 'value2',
      'field3' => 'value3'
   }
   Array[2] {
      'field1' => 'value1',
      'field2' => 'value2',
      'field3' => 'value3'
   }
}

MySQLにクエリを実行させるよりも効率的にPHP配列を「クエリ」する方法はありますか?本当にこれはすべてNoSQLソリューションを利用する絶好の機会のように聞こえますが、残念ながら、私はそれを制御できません。

[編集]

私たちは約50のデータベースに分散したデータを扱っており、それぞれに50万から5000万の行があるおそらく50のテーブルが含まれています。それはすべてレガシーであり、最適化が不十分です。私が持っているもので作業しようとしているだけです。

すべてのデータベースは同じスレーブサーバー上にあり、はい、クロスデータベースであるクエリを実行する必要があります。MySQLに作業を任せるよりも、コードを介してうまく処理できるかどうかを確認したいと思っていたのは厄介な状況です(私が聞いていることから、答えはおそらくノーです)

4

2 に答える 2

1

実行しているクエリの種類によって異なりますが、ほとんどの場合、大幅なパフォーマンスの低下が見られます (言うまでもなく、何百万もの行を最初に memcache にロードする必要があるという事実は言うまでもありません。かなりの時間)。レポートを実行し、結果を memcache に保存することもできますが、それはレポートへのアクセス頻度と他のいくつかの考慮事項に大きく依存します。

実行しているレポートの種類にもよりますが、通常、数百万行に対するレポート作成に何時間もかかることはありません。レポート クエリに対して EXPLAIN を実行して、どこかで適切なインデックスを使用していないかどうか、または実行しているクエリのタイプに対してより効率的な構造を作成できる可能性があるかどうかを判断しましたか?

もう 1 つの可能性は、データベース サーバーが過負荷になっていることです。スレーブ サーバーをセットアップし、それに対してレポート クエリを実行すると、パフォーマンスが向上する可能性があります。

編集: あなたの現在の不幸な状況についてさらに情報を得た後、いくつかの可能なオプションがまだあります. スキーマや EXPLAIN の出力なしでこの状況を最適化しようとするのは非常に困難ですが、すべてのクエリを注意深く分析し、可能な最適化 (インデックスの追加など) を行うと、パフォーマンスを改善できると思います。 )。面倒です。

もう 1 つの可能性は、異なるデータベースごとに個別にレポートを実行してから、共通の場所で結果をマージすることです。

于 2012-08-15T14:20:53.270 に答える
-2

Memcachedはオブジェクトレベルのキャッシュです。SQLインターフェイスは提供しません。したがって、あなたのアイデアはmemcachedと互換性がありません。ただし、いくつかの可能性があります。

遭遇するすべてのクエリについて、最初にハッシュコードを計算します。ハッシュには、クエリに含まれるすべてのパラメータが含まれている必要があります。データを取得するときは、結果をデータ転送オブジェクト(XML /テキストなど)に変換し、ハッシュとデータオブジェクトをmemcacheに保存します。

これで、クエリを実行するたびに、最初にハッシュを作成し、キャッシュに存在するかどうかを確認します。存在する場合は取得し、データベースからフェッチしてキャッシュに配置します。

データベースを更新すると問題が発生し、キャッシュが古くなり、更新する必要があります。あなたのビジネスがそのようなものであるならば、あなたは最新のデータを無視することができます、あなたは定期的にキャッシュを無効にすることができます。つまり、データがキャッシュに存在していても、1時間前にフェッチされた場合でも、再度フェッチします。これは1つの戦略です。

また、データベースのトリガーを使用して、キャッシュとデータベースをスキャンし、疑似リアルタイムで更新するバックグラウンドプロセスを作成することもできます。データベースを更新するたびに、キャッシュの更新に使用されるメッセージが作成されます。

より複雑な方法は、すべてのデータベース更新を前処理し、更新を行う前に影響を受けるキャッシュエントリを無効にすることです。

キャッシングは簡単です。それを無効にするのは難しいです。データをキャッシュする前に、無効化を把握する必要があります。

-補遺

クエリを実行する余裕がない場合もあります。標準のjdbcインターフェースは遅すぎます。十分な呼び出しを行うことができない壁にぶつかることになるので、その時点では、それはデータベースではなく、データベースへのパスです。これについてもっと知りたい場合は、handlersocketとFacebookがクエリをスケーリングする方法について読んでください。

http://gigaom.com/cloud/facebook-shares-some-secrets-on-making-mysql-scale/

ハンドラーソケット:

http://yoshinorimatsunobu.blogspot.com/search/label/handlersocket

于 2012-08-15T14:28:16.790 に答える