1

着実に増加している商品の十分に大きなデータベースがあります。現在、DB には 1000 万を超える商品があります。

良いものとそのカテゴリーがあります。各商品には、名前、価格、販売された商品の量、保証のフラグ、および品質などの属性があります。特定のカテゴリにのみ固有の商品の特性があります。商品のプロパティは、次の形式 - 2000:10000 (プロパティのカテゴリ: プロパティの値) を持っています。プロパティの一部のカテゴリとプロパティ自体は、ブランドなどのさまざまなカテゴリで重複する場合があります。これらのカテゴリとプロパティによって、タイトルとプロパティのフィルタリング、ソート、および検索が行われます。製品は、1 つまたは複数のカテゴリにリンクできます。

最初はmysqlだけを使って、カテゴリごとにテーブルを作って商品を保管していました。このようにして、約 6 ~ 7,000 の商品付きのテーブルがありました。選択中に、オペレーターUNIONの助けを借りてリクエストをマージして、それぞれにリクエストを行いました。商品数とそのカテゴリが増えると、選択に非常に時間がかかり、mysql サーバーが停止します。この後、すべての製品を 1 つのテーブルに移動しました。テーブル構造は【以下】( http://clip2net.com/s/5OUKXm .

1,000 万の製品を含むテーブルでは、現在 mysql を使用することが難しくなっています。ソートについて話さずに、そこから選択することはまったく不可能です。スフィンクス、インデックス スフィンクスを使用しました。

sql_query = SELECT \
ti.item_id, \
ti.item_id AS iid, \
crc32(ti.item_nick) AS nick, \
ti.item_title AS title, \
ti.item_sold AS sold, \
ti.item_rating AS rating, \
ti.item_popular AS popular, \
ti.item_warranty AS warranty, \
ROUND(ti.item_price*100, 0) AS price, \
ti.item_props AS props, \
COUNT(c.comment_iid) AS comments, \
GROUP_CONCAT(tcir.category_item_ref_tid) AS tids \
FROM item AS ti \
LEFT JOIN comment AS c ON ti.item_id = c.comment_iid \
INNER JOIN category_item_ref AS tcir ON ti.item_id = tcir.category_item_ref_iid \
WHERE ti.item_id >= $start AND ti.item_id <= $end \
GROUP BY ti.item_id

sql_attr_uint = sold
sql_attr_uint = rating
sql_attr_uint = comments
sql_attr_uint = warranty
sql_attr_bigint = iid
sql_attr_bigint = nick
sql_attr_bigint = price
sql_attr_bigint = popular
sql_attr_multi = uint tids from field;

Sphinx を介した検索は高速ですが、多くの属性があり、特に検索とソートが遅くなる sql_attr_multi tid があります。60万品のサンプリング時間は約18~19秒。製品を 1 つのカテゴリのみに関連付けようとしました (属性 tids は sql_attr_uint になりました)。サンプリング時間は 3 ~ 5 秒に短縮され、これもあまり良くありません。

私が間違っていることを教えてください.Sphinxのインデックスを別の方法で構築する価値があるかもしれません. おそらく、別の方法でテーブル構造を構築するか、MySQL、MongoDB、PostgreSQL、MariaDB などのデータベースに別のプラットフォームを使用する必要があります。

4

1 に答える 1

1

大規模なデータセット セットに対応した他の多くの企業と同じように、あなたも問題に直面しています。あなたのユースケースは読み取りが重いが書き込みが少ないように見えるので幸運です:-) データベースシステムは、高速検索の最適化とともにインデックスとロックを可能にする仮想化されたファイルシステムにすぎないことを理解することが重要です(データとインデックスで)。

適切なクエリを使用して、テーブル内のほぼ 10m のアイテムを高速にする必要がない理由はありません。ただし、システムとクエリを最適化する必要があります。どういう意味ですか?

あるカテゴリの商品の高速ソートをサポートしたいとおっしゃいました。どのように設計すればよいですか?

  • 1,000 万のアイテム、10,000 のカテゴリがあり、それぞれに 100 個の良いアイテムがあるとします。
  • 1 つのカテゴリを値でソートすると、カテゴリ ID と価格値の両方を含むインデックスの形式で、カテゴリと価格の両方のデータが重複してソートされます。
  • 適切な方法で実行されたクエリは、このインデックスを使用するだけです。まず第一に、インデックスの形式である種のハッシュテーブルを使用して表されるため、高速なカテゴリを検索します。たとえば、MS SQL はハード (ドライブ) 内に 512kb をキャッシュします。 ) 読んだ。インデックスで必要なカテゴリを見つけたら、並べ替えられた 100 個のアイテムを取得して、ドライブで見つける必要がある物理行 ID のコレクションを取得しました。最後のステップは、ランダムに選択された識別子であっても数ミリ秒かかる可能性がある id の 100 のデータベース行を物理的に読み取ることです。

このセクションを書いた目的は、1 つの大きなデータベース テーブルでもクエリに対して高速である可能性がありますが、クエリを調整し、特定の適切なインデックスを提供する必要があることです。

古典的なアプローチを試す必要があります:

  1. ユースケースを書く - システムで最適化したい上位のクエリはどれですか?
  2. これらのクエリを使用して、テーブルとインデックスを最適化します

データをより多くのテーブルに分割する必要はないように思われます。上記のアプローチを使用して、クエリが検索する必要があるデータの量を排除する必要があります。正しいインデックスを使用するだけです。

テーブルの結合について言及しました。大規模なデータの場合は非常に長い操作になる可能性があるため、一般的なシステムは、データを複製し、1 つのテーブルのみを提供して (最速のアプローチ)、他のテーブルから複製データを検索することです。2 つのテーブルをアトミックに更新する必要があるため、明らかな問題はこのデータの更新です。読み取り専用について話したら、それは実際の問題ではないように思えます。元のデータを更新するときに、複製されたデータを更新するだけです。

大量の読み取りと書き込みに対処する方法が他にもいくつかあります。Twitter や Facebook などのトップ インターネット企業のアーキテクチャを研究し、同様の問題にどのように対処しているかを調べるのはよいことです。

于 2013-09-25T20:10:21.403 に答える