ホームページ >データベース >mysql チュートリアル >より高速なランダム行選択のために MySQL の ORDER BY RAND() 関数を最適化するにはどうすればよいですか?
より高速なランダム行選択のための 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 サイトの他の関連記事を参照してください。