10

2 つのアプリケーション (本とリーダー) を持つプロジェクトがあります。

Books アプリケーションには、次のフィールドを持つ 400 万行のテーブルがあります。

 book_title = models.CharField(max_length=40)
 book_description = models.CharField(max_length=400)

400万行のデータベースにクエリを実行することを避けるために、件名で分割することを考えています(200.000行の20テーブルを持つ20モデル( book_horror、book_drammatic、ecc ))。

「リーダー」アプリケーションでは、このフィールドを挿入することを考えています:

reader_name = models.CharField(max_length=20, blank=True)
book_subject = models.IntegerField()
book_id = models.IntegerField()

したがって、ForeignKey の代わりに、整数の「book_subject」(適切なテーブルにアクセスできるようにする) と「book_id」(「book_subject」で指定されたテーブル内の本にアクセスできるようにする) を使用することを考えています。

400万行のテーブルをクエリすることを避ける良い解決策はありますか?

代替ソリューションはありますか?

ありがとう^__^

4

6 に答える 6

15

多くの人が言っているように、テーブルを小さなテーブルに分割するのは少し時期尚早です (水平分割またはシャーディング)。データベースはこのサイズのテーブルを処理するように作られているため、パフォーマンスの問題はおそらく別の場所にあります。

インデックスは最初のステップですが、これを行ったようです。データベースがインデックスで処理するには、400 万行で十分です。

次に、実行中のクエリの数を確認します。これは、django デバッグ ツールバーのようなもので行うことができます。多くの場合、不要なクエリが作成されていることに驚かれることでしょう。

キャッシングは次のステップです。ほとんどのユーザーにとって変更されていないページまたはページの一部には memcached を使用します。これは、わずかな労力で最大のパフォーマンス向上が見られる場所です。

本当にテーブルを分割する必要がある場合は、最新バージョンの django (1.2 alpha) でシャーディング (マルチ DB など) を処理できます。これを行う方法)。表を分割するためにジャンルを使用しないでください。絶対に変更しないものを選択し、クエリを作成するときに常に知っているものを選択してください。著者のように、姓の頭文字か何かで割ります。これは多大な労力を要し、それほど大きくないデータベースには多くの欠点があります --- これが、ここにいるほとんどの人がそうしないようにアドバイスしている理由です!

[編集]

非正規化を省略しました!一般的なクエリでの結合を防ぐために、一般的なカウント、合計などをたとえば作成者テーブルに入れます。欠点は、(django が DenormalizedField を追加するまで) 自分で保守する必要があることです。明確で単純なケースの開発中、またはキャッシングが失敗した後---ただし、シャーディングまたは水平パーティショニングのかなり前に、これを確認します。

于 2010-01-12T20:20:11.893 に答える
11

ForeignKeyはデータベースと同じように実装されIntegerFieldているため、モデルが機能しなくなるという犠牲を払って節約することはほとんどありません。

編集: ピートのために、それを1つのテーブルに保持し、必要に応じてインデックスを使用してください。

于 2010-01-12T18:50:00.297 に答える
1

パフォーマンスに問題がありますか? その場合は、いくつかのインデックスを追加する必要があるかもしれません。

インデックスが役立つ場所を把握する 1 つの方法は、db サーバーのクエリ ログを調べることです (MySQL を使用している場合は、こちらの手順を参照してください)。

パフォーマンスの問題がない場合は、そのまま使用してください。データベースは何百万ものレコードを処理するように作られています.djangoは賢明なクエリを生成するのが得意です.

于 2010-01-12T19:10:05.450 に答える
1

私は Django には詳しくありませんが、DB については大まかに理解しています。

大規模なデータベースがある場合、データベースのインデックスを作成するのはごく普通のことです。そうすれば、データの取得はかなり速くなるはずです。

ブックをリーダーに関連付ける場合は、リーダーをブックにリンクする別のテーブルを作成する必要があります。

本をテーマごとに分けるのは悪い考えではありません。しかし、20 のアプリケーションがあるということで、あなたが何を意味するのかわかりません。

于 2010-01-12T19:02:51.580 に答える
1

このタイプの問題に対する一般的なアプローチは、シャーディングです。残念ながら、それを実装するのは主に ORM 次第であり (Hibernate はそれを見事に実行します)、Django はこれをサポートしていません。ただし、400万行が本当に悪いかどうかはわかりません。クエリは引き続き完全に管理できるはずです。

おそらく、memcachedのようなものでキャッシングを調べる必要があります。Djangoはこれを非常によくサポートしています。

于 2010-01-12T19:16:38.063 に答える
1

使用しているデータベースについては言及していません。MySQL や PostgreSQL などの一部のデータベースには、すぐに使用できる非常に保守的な設定があり、小さなサーバー上の小さなデータベース以外には基本的に使用できません。

使用しているデータベースと、それが実行されているハードウェア、およびそのハードウェアが他のアプリケーションと共有されているかどうか (たとえば、Web アプリケーションにもサービスを提供しているかどうか) をお知らせいただければ、特定の調整を提供できる場合があります。アドバイス。

たとえば、MySQL では、おそらく InnoDB 設定を調整する必要があります。PostgreSQL の場合、shared_buffers やその他の多くの設定を変更する必要があります。

于 2012-03-05T11:35:02.337 に答える