3

「アイテム」のテーブルと「アイテムキーワード」のテーブルがあります。ユーザーがキーワードを検索するとき、結果の 1 ページと結果の総数をユーザーに提供したいと考えています。

私が現在行っていることは(「ab c」を検索するユーザーの場合:

SELECT DISTINCT {fields I want} FROM itemkeywords JOIN items   
    WHERE (keyword = 'a' or keyword='b' or keyword='c'
    ORDER BY "my magic criteria"
    LIMIT 20.10

そして、カウントで同じクエリを実行します

SELECT COUNT(*) FROM itemkeywords JOIN items   
    WHERE (keyword = 'a' or keyword='b' or keyword='c'

これはかなり大きなテーブルを取得する可能性があり、このソリューションは非常に悪いと思います...
しかし、これ以上良いものは思いつきません。

MySQL を 2 回ヒットすることを回避するための明白な代替手段は、LIMIT 句なしで最初のクエリのみを実行し、次に正しいレコードに移動して対応するページを表示し、次に結果をカウントするためにレコードセットの最後に移動するようですさらに悪いことに...

何か案は?

注: PHP ではなく、ASP.Net と MySQL を使用しています。

4

4 に答える 4

5

限定選択の選択の後に SQL_CALC_FOUND_ROWS を追加し、最初の選択が終了した後に「SELECT FOUND_ROWS()」を実行します。

例:

mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
    -> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();
于 2008-09-28T16:47:00.307 に答える
1

パフォーマンスが本当に心配で、最終的に 2 つのクエリを作成する必要がある場合は、一致の合計数をキャッシュすることを検討することをお勧めします。これは、ユーザーが結果のページを閲覧しても変化しないためです。

于 2008-11-10T03:43:05.343 に答える
0

次の 2 つのオプションがあります。

MySQL API には、行数を返す関数が必要です。古い API の mysql_num_rows() を使用します。バッファリングされていないクエリを使用している場合、これは機能しません。

より簡単な方法は、両方のクエリを組み合わせることです。

SELECT DISTINCT {fields I want}, count(*) as results 
       FROM itemkeywords JOIN items   
       WHERE (keyword = 'a' or keyword='b' or keyword='c'
       ORDER BY "my magic criteria"
       LIMIT 20.10

いくつかのテストを行いましたが、count(*) 関数は limit 句の影響を受けません。これをDESCRIBE最初にテストします。クエリの速度にどの程度影響するかはわかりません。最初の 10 件の結果のみを取得する必要があるクエリは、カウントのすべての結果を検索してから最初の 10 件を検索する必要があるクエリよりも短くする必要がありますが、ここで間違っている可能性があります。

于 2008-09-28T16:48:54.873 に答える
0

最初のステートメントで MySQL SQL_CALC_FOUND_ROWSを調べ、その後に 2 番目のステートメントSELECT FOUND_ROWS()を続けると、少なくとも 2 つのデータ クエリを実行できなくなりますが、それでもテーブル全体のスキャンを 1 回実行する傾向があります。

http://dev.mysql.com/doc/refman/5.0/en/select.htmlおよび http://dev.mysql.com/doc/refman/5.0/en/information-functions.htmlを参照してください。

検討することをお勧めします:本当にこの機能が必要ですか?

于 2008-09-28T16:50:02.530 に答える