0

多くの e コマース サイトで見られるように、製品のページネーションとフィルタリングを処理するときにパフォーマンスの問題が発生しています。Zappos の例を次に示します。

標準の種類:
132 件中 1-10 件を表示しています。[前] 1 2 [3] 4 ... 13 [次]
[10] ページごとの結果

私には、問題の大部分は、クエリが 2 回実行されることのように思えます。以下は「フィルター」クエリです。

SELECT product_id, product_title, orderable
FROM table_view
WHERE (family_title = 'Shirts' OR category_title = 'Shirts')
AND ((detail_value = 'Blue' AND detail_title = 'Color')
OR (detail_value = 'XL' AND detail_title = 'Size'))
GROUP BY product_id, product_title, orderable
HAVING COUNT(detail_title)=2
ORDER BY product_id
LIMIT 10 OFFSET 0

クエリは、単独で実行するのに約 20 ミリ秒かかります。選択元のテーブルは、約 5 つの異なるテーブルを結合したビューです。ユーザーから渡されるパラメータは、フィルタリング基準である「detail_value」と「detail_title」です。「ファミリー」と「カテゴリ」、そして「ページあたりの結果」によって制限が設定されます。したがって、すべての結果を表示したい場合、制限は 2000 に設定されます。また、ページネーションを介して新しいページに移動するたびに、クエリ全体が再度実行されます。以下は PHP のスニペットです。$products はクエリ結果の配列です。そして、$number_of_results は、上限のある同じもののカウントです。

$products = filter($value, $category_title, $number_per_page, $subcategory, $start_number);

$number_of_results = count(filter($value, $category_title, 2000, $subcategory, 0));

$pages = ceil($number_of_results / $number_per_page);

ローカル マシンで実行すると、結果ページの読み込みに約 600 ~ 800 ミリ秒かかります。Heroku にデプロイすると、ページの読み込みに 13 ~ 16 秒かかります。多くの PHP コードを省略しましたが、PHP の PDO クラスを使用して、クエリ結果を PHP で表示するオブジェクトにしています。結合されるテーブルは、製品テーブル、カテゴリ テーブル、詳細テーブル、およびそれらを外部キーでリンクする 2 つのテーブルです。

Google の結果は、これがかなり一般的で複雑な問題であることを示していますが、私にとって有効な実際の解決策はまだ見つけていません。

4

1 に答える 1

0

ページネーションの多くのクエリは、通常、数回実行する必要があります。1回は表示されるレコードの数を決定し、次にもう一度レコードの画面を取得します。次に、レコードの次の画面を取得する後続のクエリなど。

ページネーションクエリを遅くする2つの解決策は次のとおりです。

  1. カーソルを使用して、開いているクエリ結果セットからnレコードをプルします
  2. クエリを高速化

解決策1は、サーバーのリソースに対してメモリ的にコストがかかる可能性があり、このようなクエリを生成する同時ユーザーが多数いる場合は、拡張性が高くない可能性があります。また、使用しているPDOクラスでカーソルを実装するのは難しい場合があります。

解決策2は、ビュークエリの改善、インデックスの追加などによって実行できます。ただし、それだけでは不十分な場合があります。テーブルが書き込まれるよりもはるかに頻繁に読み取られる場合は、UPDATE / INSERT/DELETEトリガートリックを使用してみてください。VIEWに対してクエリを実行するのではなく、VIEWと同じ列構造とデータを使用してテーブルを作成します。基になるテーブルの1つが変更されたときはいつでも、変更に従うようにこの新しいテーブルを手動で変更してください。これにより書き込みは遅くなりますが、読み取りは大幅に向上します。

于 2012-08-15T21:05:50.483 に答える