1

現在、私は非常に高度な PHP 開発者であり、小規模な MySQL セットに精通していますが、最近参加したスタートアップのために大規模なインフラストラクチャを構築しており、そのサーバーは毎日約 100 万行のデータをプッシュしています。巨大なサーバー パワーと以前のアーキテクチャ。

データベース サイズが 394.4 ギガバイトの大きなデータ セット (現在 8,490 万行) を検索する最善の方法を知る必要があります。Amazon RDS を使用してホストされているため、ダウンタイムや速度低下はありません。大規模なデータ セットに内部的にアクセスするための最良の方法を知りたいだけです。

たとえば、8,400 万行のデータベースを検索する場合、6 分かかります。これで、特定の ID またはタイトルに直接リクエストを送信すると、すぐにそれが提供されます。では、大規模なデータ セットを検索するにはどうすればよいでしょうか。

1 つの変数を渡してデータベースから情報を検索するのは高速ですが、検索の実行速度は非常に遅くなります。

MySQL クエリの例:

SELECT u.*, COUNT(*) AS user_count, f.* FROM users u LEFT JOIN friends f ON u.user_id=(f.friend_from||f.friend_to) WHERE u.user_name LIKE ('%james%smith%') GROUP BY u.signed_up LIMIT 0, 100

8,400 万行未満のクエリは非常に低速です。具体的には、このクエリをスタンドアロンで実行するのに 47.41 秒かかります。何かアイデアはありますか?

私が必要とするのは、その課題が分類され、ドリフトを取得できることだけです. また、MySQL は大規模なデータ セットや Oracle や MSSQL などにはあまり適していませんが、現時点では他のデータベース ソリューションではなく MySQL で再構築するように言われています。

4

2 に答える 2

3

LIKEさまざまな理由で非常に遅いです:

  • LIKE式が定数で始まらない限り、インデックスは使用されません

    たとえば、インデックス作成LIKE ('james%smith%')には良いですが、悪いです。あなたの例では、 " " フィールドLIKE ('%james%smith%')にインデックスを使用しません。user_name

  • 文字列の照合は、通常の演算子に比べて (アルゴリズム的に) 複雑です。

解決する:

  • LIKEそのフィールドに使用できるインデックスがある場合は、式がワイルドカードではなく定数で始まることを確認してください。

  • 単語全体を検索する場合は、インデックス テーブルを作成することを検討してください (データベース インデックス コンテキストではなく、「インデックス」という単語の文献/ライブラリ コンテキストで)。または、ランダムで頻繁に繰り返される部分文字列を検索する場合は、部分文字列ルックアップ テーブル。

    たとえば、すべてのユーザー名が「FN LN」または「LN、FN」の形式である場合 - それらを分割し、名および/または姓を辞書テーブルに格納し、クエリでそのテーブルに結合します (そして、単純に等しいことを行います)。 .

于 2010-08-02T00:58:45.890 に答える
1
LIKE ('%james%smith%')

ペストのようなこれらのものを避けてください。一般的な DBMS で最適化することは不可能です。

正しい方法は、データが挿入または更新される時点でこのようなもの (姓名) を計算して、すべての読み取りでコストが償却されるようにすることです。これは、2 つの新しい列 (インデックス付き) を追加し、挿入/更新トリガーを使用することで実行できます。

または、列内のすべての単語が必要な場合は、トリガーでデータを単語に分割し、アプリケーション レベルのインデックス テーブルを使用して、関連するレコードを検索します。たとえば、次のようになります。

main_table:
    id integer primary key
    blah blah blah
    text varchar(60)
appl_index:
    id index
    word varchar(20)
    primary key (id,word)
    index (word)

次に、 abominable よりもはるかに高速に、との両方を含む を検索appl_indexするためにクエリを実行できます。実際の単語を別のテーブルに分割して単語 ID を使用することもできますが、それは好みの問題です。パフォーマンスへの影響は疑わしいでしょう。idjamessmithlike '%...'

同様の問題f.friend_from||f.friend_toが発生する可能性がありますが、その構文は前に見たことがありません (そうであるように、コンテキストがu.user_idどちらか一方になる可能性がある場合)。

基本的に、データベースをスケーリングしたい場合は、選択で行ごとの関数のように見えることさえしないでください。8400 万行が構成テーブルのサイズに相当するメインフレーム データベースで作業している誰かからそれを聞いてください :-)

そして、すべての最適化の質問と同様に、推測ではなく測定してください。

于 2010-08-02T01:02:03.900 に答える