3

挨拶!

次の問題があります。膨大な数の行を含むテーブルがあり、検索してから、検索結果を多くのパラメーターでグループ化する必要があります。テーブルが

id, big_text, price, country, field1, field2, ..., fieldX

そして、このようなリクエストを実行します

SELECT .... WHERE 
[use FULLTEXT index to MATCH() big_text] AND 
[use some random clauses that anyway render indexes useless, 
like: country IN (1,2,65,69) and price<100]

これは検索結果として表示されます。次に、これらの検索結果を取得し、いくつかのフィールドでグループ化して、検索フィルターを生成する必要があります。

(results) GROUP BY field1
(results) GROUP BY field2
(results) GROUP BY field3
(results) GROUP BY field4

これは私が必要としているものの単純化されたケースです。手元にある実際のタスクはさらに問題があります。たとえば、最初の結果クエリが独自のGROUPBYも実行する場合があります。そして、そのような機能の例は、このサイト http://www.indeed.com/q-sales-jobs.html (検索結果と左側のフィルター)です。

私はMySQLがどのように機能するかについて深く研究してきましたが、現時点では、MySQLでこれが可能であるとはまったく考えていません。大まかに言えば、MySQLテーブルはHDD上にある行のヒープにすぎず、インデックスはこれらのテーブルの小さなバージョンであり、インデックスフィールドでソートされ、実際の行を指します。もちろん、これは非常に単純化されていますが、要点は、これを修正する方法、つまり、複数のインデックスを使用して、高速のGROUP BYを実行できる方法がわかりません(クエリがGROUPに到達するまでに) BYインデックスは、範囲検索などのためにまったく役に立ちません)。MySQL(または同様のデータベース)には、インデックスのマージ、緩いインデックススキャンなど、さまざまな便利な機能があることを知っていますが、これは単に適切ではありません。上記のクエリの実行には、それでも永遠に時間がかかります。

この問題は、集計タスクなど、データを保存および処理するための根本的に新しい方法を利用するNoSQLによって解決できると言われました。私が知りたいのは、これがどのように行われるかについての簡単な概略説明です。つまり、それがどのように可能であるかが今のところ理解できないので、それが実際にそれを行っていることを実際に確認できるように、それをざっと見たいだけです。つまり、データはまだデータであり、メモリに配置する必要があり、インデックスはすべての制限があるインデックスです。これが実際に可能であれば、NoSQLの詳細な調査を開始します。

PS。NoSQLに関する大きな本を読みに行くように言わないでください。私はすでにMySQLに対してこれを行っていますが、私の場合は使用できないことがわかりました:)ですから、大きな本を手に入れる前に、テクノロジーについて予備的な理解をしたかったのです。

ありがとう!

4

1 に答える 1

12

「NoSQL」には基本的に4つのタイプがありますが、実際には4つのうち3つは十分に類似しているため、その上にSQL構文を記述できます(MongoDBとそれはクレイジーなクエリ構文です[Javascriptは私の1つですが好きな言語])。

Key-Valueストレージ

これらはRedisのような単純なNoSQLシステムであり、基本的には非常に洗練されたハッシュテーブルです。後で取得したい値があるので、それにキーを割り当ててデータベースに詰め込みます。一度にクエリできるのは1つのオブジェクトだけで、1つのキーだけです。

あなたは間違いなくこれを望んでいません。

ドキュメントストレージ

これは、Key-Valueストレージよりも一歩進んだものであり、ほとんどの人がNoSQL(MongoDBなど)と言うときに話します。

基本的に、これらは階層構造(XMLファイル、JSONファイル、およびコンピューターサイエンスの他の種類のツリー構造など)を持つオブジェクトですが、ツリー上のさまざまなノードの値にインデックスを付けることができます。結合時のパフォーマンスを犠牲にするため、ルックアップ時の従来の行ベースのSQLデータベースに比べて「速度」が高くなります。

大量の列を持つ単一のテーブルからMySQLデータベースのデータを検索していて(ビュー/仮想テーブルではないと想定)、クエリに対して適切にインデックスが作成されていると想定している場合(これは、ここで実際の問題になる可能性があります) 、MongoDBのようなドキュメントデータベースはMySQLに比べてBig-Oのメリットをもたらさないため、この理由だけで移行することはおそらく望ましくありません。

列型ストレージ

これらはSQLデータベースに最もよく似ています。実際、SQL構文を実装するもの(Sybaseなど)と実装しないもの(Cassandra)があります。データは行ではなく列に格納されるため、追加と更新にはコストがかかりますが、各列には基本的に暗黙的にインデックスが付けられるため、ほとんどのクエリは安価です。

ただし、クエリでインデックスを使用できない場合は、通常のSQLデータベースよりも列指向ストアの方が適しています。

グラフストレージ

グラフデータベースはSQLを超えて拡張されます。Key-Value、ドキュメントデータベース、SQLデータベースなど、グラフ理論で表現できるものはすべて、neo4jのようにグラフデータベースで表現できます。

グラフデータベースは、これを行うために(ドキュメントデータベースとは対照的に)結合を可能な限り安価にしますが、単純な「行」クエリでさえ取得するために多くの結合を必要とするため、そうする必要があります。

テーブルスキャンタイプのクエリは、データを取得するためのすべての追加の結合(ばらばらに格納されている)があるため、標準のSQLデータベースよりも遅くなる可能性があります。

それで、解決策は何ですか?

あなたはおそらく私があなたの質問に正確に答えていないことに気づいたでしょう。「終了しました」と言っているわけではありませんが、本当の問題はクエリがどのように実行されているかです。

  1. データのインデックスを作成するのが難しいと確信していますか?特定のクエリのパフォーマンスを向上させる可能性のある複数列キーなどがあります。MicrosoftのSQLServerには、提供した例に適用できるフルテキストキータイプがあり、 PostgreSQLはそれをエミュレートできます
  2. ほとんどのNoSQLデータベースがSQLデータベースよりも優れているのは、Map-Reduceです。具体的には、クエリ制約を記述できる高速で実行される完全なチューリング完全言語の統合です。クエリ関数は、すばやく「失敗」するように記述できます。一致しないクエリを削除するか、「優先度」の要件を満たすレコードですぐに成功して戻る一方で、SQLで同じことを行うのは少し面倒です。

ただし、最後に、解決しようとしている正確な問題:オプションのフィルタリングパラメータを使用したテキスト検索は、より一般的にはとして知られておりsearch engine、この特定の問題を処理するための非常に特殊なエンジンがあります。これらのクエリを実行するには、ApacheSolrをお勧めします。

基本的に、テキストフィールド、「フィルター」フィールド、およびテーブルの主キーをSolrにダンプし、テキストフィールドにインデックスを付け、クエリを実行します。その後、完全なレコードが必要な場合は、SQLデータベースにクエリを実行します。 Solrから取得した特定のインデックス。それはもう少しメモリを使用し、2番目のプロセスを必要としますが、おそらくここであなたのニーズに最も適しています。

なぜこのテキストのすべてがこの答えに到達するのですか?

質問のタイトルは質問の内容とはまったく関係がないので、両方に答えました。:)

于 2012-03-22T20:13:13.647 に答える