ホームページ > データベース > mysql チュートリアル > より高速なランダム行選択のために MySQL の ORDER BY RAND() 関数を最適化するにはどうすればよいですか?

より高速なランダム行選択のために MySQL の ORDER BY RAND() 関数を最適化するにはどうすればよいですか?

Linda Hamilton
リリース: 2024-12-19 22:40:15
オリジナル
584 人が閲覧しました

How Can I Optimize MySQL's ORDER BY RAND() Function for Faster Random Row Selection?

より高速なランダム行選択のための MySQL の ORDER BY RAND() 関数の最適化

MySQL の ORDER BY RAND() 関数は、ランダムな行の選択に広く使用されていますテーブルの行。ただし、特に大規模なテーブルや頻繁な更新の場合、非効率になる可能性があります。この非効率性は遅いクエリ ログで明らかであり、ORDER BY RAND() を含むクエリが速度低下に大きく寄与しています。

考えられる解決策の 1 つは、クエリを複数のサブクエリに分割する MySQLPerformanceBlog のメソッドです。ただし、この手法はすべての状況で適切であるとは限りません。

代替アプローチ

効率を向上させる代替アプローチを以下に示します。

SELECT  *
FROM    (
        SELECT  @cnt := COUNT(*) + 1,
                @lim := 10
        FROM    t_random
        ) vars
STRAIGHT_JOIN
        (
        SELECT  r.*,
                @lim := @lim - 1
        FROM    t_random r
        WHERE   (@cnt := @cnt - 1)
                AND RAND(20090301) < @lim / @cnt
        ) i
ログイン後にコピー

このメソッドは、2 つの変数に基づいて選択される各行の実行確率を計算することによって動作します。 STRAIGHT_JOIN を使用すると、結果内の行の順序が保持され、効果的にランダムな選択が可能になります。

特定のケース: 単一のランダム レコードの選択

要件が次の場合単一のランダム レコードを選択するには、次のクエリを使用できます。

SELECT  aco.*
FROM    (
        SELECT  minid + FLOOR((maxid - minid) * RAND()) AS randid
        FROM    (
                SELECT  MAX(ac_id) AS maxid, MIN(ac_id) AS minid
                FROM    accomodation
                ) q
        ) q2
JOIN    accomodation aco
ON      aco.ac_id =
        COALESCE
        (
        (
        SELECT  accomodation.ac_id
        FROM    accomodation
        WHERE   ac_id > randid
                AND ac_status != 'draft'
                AND ac_images != 'b:0;'
                AND NOT EXISTS
                (
                SELECT  NULL
                FROM    accomodation_category
                WHERE   acat_id = ac_category
                        AND acat_slug = 'vendeglatohely'
                )
        ORDER BY
                ac_id
        LIMIT   1
        ),
        (
        SELECT  accomodation.ac_id
        FROM    accomodation
        WHERE   ac_status != 'draft'
                AND ac_images != 'b:0;'
                AND NOT EXISTS
                (
                SELECT  NULL
                FROM    accomodation_category
                WHERE   acat_id = ac_category
                        AND acat_slug = 'vendeglatohely'
                )
        ORDER BY
                ac_id
        LIMIT   1
        )
        )
ログイン後にコピー

このクエリは、 ac_id 値。

これらの代替アプローチを採用すると、ORDER BY RAND() 関数を含む MySQL クエリのパフォーマンスを大幅に向上させることができます。

以上がより高速なランダム行選択のために MySQL の ORDER BY RAND() 関数を最適化するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート