1

非常に遅い次のクエリに問題があります。

    B から A.* を選択  
    A.id=B.fk_A の内部結合 A  
    WHERE A.creationDate BETWEEN '20120309' AND '20120607'  
    GROUP BY A.id  
    RAND()で並べ替え
    リミット 0,5

説明 :

    id select_type テーブル タイプ possible_keys キー key_len ref 行 エクストラ
    1 SIMPLE B インデックス fk_A fk_A 4 \N 58962 インデックスの使用。一時的な使用; ファイルソートの使用
    1 SIMPLE A eq_ref PRIMARY,creationDate PRIMARY 4 B.fk_A 1 where の使用

インデックス :

    A.id (int) = PRIMARY インデックス
    A.creationDate (日付) = インデックス
    B.fk_A = インデックス

最適化するものはありますか?

アドバイスありがとうございました

4

2 に答える 2

1

RAND()関数は、すべての行に対してRand()値を作成すると思います(これがusing temporary表示される理由filesortであり、インデックスを使用できないためです。

最良の方法はSELECT MAX(id) FROM a、最大値を取得することです。次に、1とMAX(id)の間に5つの乱数を作成し、SELECT ... WHERE a.id IN (...)クエリを実行します。

結果の行が5行未満の場合(レコードが削除されたため)、問題がなくなるまで手順を繰り返します(または、最初に100個の乱数を作成し、クエリを5個に制限します。

コードでロジックを実行する必要があるため、これは100%mysqlソリューションではありませんが、はるかに高速になると思います。

Update Just Foundは、基本的に同じことを伝える興味深い記事をネットで見つけました:http: //akinas.com/pages/en/blog/mysql_random_row/

于 2012-06-08T07:50:45.887 に答える
1

クエリの可能な書き換えの 1 つ:

SELECT A.*
FROM A   
WHERE A.creationDate BETWEEN '20120309' AND '20120607'  
  AND EXISTS
      ( SELECT *
        FROM B
        WHERE A.id = B.fk_A
      )  
ORDER BY RAND() 
LIMIT 0,5
于 2012-06-08T09:14:18.300 に答える