1

私のjspアプリケーションには、ユーザーがデータベース内のユーザー名を検索できる検索ボックスがあります。キーストロークごとに ajax 呼び出しを送信し、入力された文字列で始まる 5 つのランダムな名前を取得します。以下のクエリを使用しています。 select userid,name,pic from tbl_mst_users where name like 'queryStr%' order by rand() limit 5 しかし、テーブルに 2000 を超えるレコードがあるため、これは非常に低速です。

時間がかからず、同じことを達成できるより良いアプローチはありますか..? ランダムな値が必要です。

4

2 に答える 2

1
  1. テーブルには名前のインデックスがありますか?適用しない場合

2.MediaWikiは興味深いトリックを使用しています(WikipediaのSpecial:Random機能の場合):記事を含むテーブルには、(記事の作成時に生成される)乱数を含む追加の列があります。ランダムな記事を取得するには、乱数を生成し、[乱数]列の値が次に大きいまたは小さい(どちらかを思い出さないでください)記事を取得します。インデックスを使用すると、これは非常に高速になります。(そしてMediaWikiはPHPで書かれており、MySQL用に開発されています。)

結果の数値が適切に分散されていない場合、このアプローチは問題を引き起こす可能性があります。IIRC、これはMediaWikiで修正されているので、この方法で行うことにした場合は、コードを調べて現在どのように行われているかを確認する必要があります(おそらく、乱数列を定期的に再生成します)。

3.http://jan.kneschke.de/projects/mysql/order-by-rand/

于 2012-06-17T05:13:32.787 に答える
1

「非常に遅い」とは、秒単位でどれくらい遅いですか?

クエリが遅くなる理由は、 にインデックスを配置していない可能性が最も高いですname。2000 行は、MySQL が処理するのに簡単なはずです。

もう 1 つの考えられる理由は、SELECT句に多数の列があることです。この場合、MySQL エンジンは、この大きな結果セットをソートする前に、まずこのすべてのデータを一時テーブルにコピーすると仮定します

できるだけ長くインデックスのみを使用するように、次のことをお勧めします。

SELECT userid, name, pic
FROM tbl_mst_users
JOIN (
    -- here, MySQL works on indexes only
    SELECT userid
    FROM tbl_mst_users
    WHERE name LIKE 'queryStr%'
    ORDER BY RAND() LIMIT 5
) AS sub USING(userid); -- join other columns only after picking the rows in the sub-query.

この方法は少し優れていますが、まだ十分に拡張できません。ただし、小さなテーブルには十分なはずです (実際、2000 行は小さいです)。

@ user1461434 が提供するリンクは非常に興味深いものです。パフォーマンスがほぼ一定のソリューションについて説明します。唯一の欠点は、一度に 1 つのランダム行しか返さないことです。

于 2012-06-17T06:45:42.667 に答える