web-dev-qa-db-ja.com

並べ替えアルゴリズムを使用してWebページに結果を返す最も効率的な方法

最近、ユーザーが検索基準を入力できる検索ページを作成しています。サーバー側では、スコアリングとソートのアルゴリズムを使用して、「最良の」結果を最初に返します。現在のフローは次のようになります。

  1. ユーザーは自分の検索基準を入力します。
  2. サーバー側コード(PHP)は、その基準に一致するすべての結果をフェッチするクエリを作成します。
  3. サーバーは関数を使用して、各結果に「スコア」を割り当てます。
  4. サーバーはすべての結果をループし、「クイックソート」アルゴリズムを使用して、結果を最高スコアから最低スコアの順に並べます。
  5. 配列は、上位15件の結果のみを取得するために接合されます。これらは、結果として表示されるWebページに渡されます。

結果の下部には、「さらに読み込む」ボタンがあります。これをクリックすると、上記と同じプロセス(AJAXを介して)が実行されますが、代わりに配列を特定の量だけオフセットしますが、結果に追加する前に、次の15件の結果のみを取得し、JSONとしてWebページに返します。 JavaScript経由。

検討後、これは本当に非効率的です。ページが読み込まれるか、[さらに読み込む]がクリックされるたびにデータベースにクエリを実行して一致する結果を取得し、スコアを付けてすべてを並べ替えますが、これらの結果のうち15件のみを取得します。

もちろん、15からではなく、テーブル全体の「最良の」結果を提供するために、一致するすべての結果をクエリする必要があります。

私はそれを行うためのより良い方法を考えていました、cronjobを介してテーブル全体を並べ替えてスコアを付け、各行に「位置評価」を与えることです。ユーザーがWebページをロードするとき、一致する結果をデータベースにクエリし、同じSQLステートメントで、それらを「位置評価」列で並べ替えて、結果を15に制限します(AJAX query)。

このプロセスはもっと速くなりますか?私が考えることができる唯一の欠点は、cronjobが結果をソートする頻度に応じて、レーティングが古くなることです。

この新しいプロセスに変更する価値がありますか、それともここでの効率の問題は根拠がないのですか?

3
Conor Hughes

ここでの効率の問題は根拠がないのですか?

コストがかかる可能性のある変更のルートに進む前に、現在のソリューションをベンチマークして、現時点でリリースするのに十分なパフォーマンスがあるかどうかを確認することをお勧めします。これは、データベースのアイテム数、サービスのユーザー数、および使用されるアルゴリズムに基づいて当てはまる場合と当てはまらない場合があります。サーバーの運用ワークロードを測定または推定し、応答の遅延をテストして、アルゴリズムisが遅すぎるかどうかを確認します。これは可能性があるの場合、それは開発ではない可能性があるためです優先。


本当にそうであることがわかった場合は、そこからいくつかのルートに進むことができます。

  • (Dan Wilsonのコメントで提案されているように)モデルを調整して、フルテキストランキングで行にインデックスを付けます。これは、効率が大幅に向上する可能性のある、最も変化の少ない経路です。私は純粋なSQLテキスト検索ソリューションのスペシャリストではありませんが、適切なスコアリングの柔軟性に関していくつかの制限があることを期待しています。

  • 関連性のあるマッチングには、テキスト検索指向のデータベースを使用してください。 Elasticsearch(提携していません)。これは、生のテキストマッチングを実行するのではなく、きめ細かい関連性検索が必要な場合に私が好むものですが、これには、関連する制約が多い2つのベースにデータを分割するという代償が伴います。

  • JavaScriptでランク付けとフィルタリングを行います。これは、多数のクライアントの時間応答に重点を置き、アイテムのセットが(10k未満のスペクトルで)少数の場合、賢明なルートです。ただし、セットが拡張する可能性が高い場合は、ページの読み込みに大きな影響が出る可能性があります。

  • この問題には、検索APIまたはサービスを使用してください。 Algolia(提携していません)。これは、機能と品質を損なうことなく開発時間を最小限にしたいが、外部サービスに依存することが目的ではない場合、賢明なルートです。

2
Arthur Havlicek