プロジェクトの既存のクエリの多くを最適化しています。Quassnoiのソリューションは、クエリを大幅に高速化するのに役立ちました。ただし、特に複数の大きなテーブルで多くのサブクエリを含む複雑なクエリの場合、すべてのクエリに上記のソリューションを組み込むのは難しいと思います。
したがって、私はあまり最適化されていないソリューションを使用しています。基本的には、Quassnoiのソリューションと同じように機能します。
SELECT accomodation.ac_id,
accomodation.ac_status,
accomodation.ac_name,
accomodation.ac_status,
accomodation.ac_images
FROM accomodation, accomodation_category
WHERE accomodation.ac_status != 'draft'
AND accomodation.ac_category = accomodation_category.acat_id
AND accomodation_category.acat_slug != 'vendeglatohely'
AND ac_images != 'b:0;'
AND rand() <= $size * $factor / [accomodation_table_row_count]
LIMIT $size
$size * $factor / [accomodation_table_row_count]
ランダムな行を選択する確率を計算します。rand()は乱数を生成します。rand()が確率以下の場合、行が選択されます。これにより、ランダムな選択が効果的に実行され、テーブルサイズが制限されます。定義された制限カウントより少ない値を返す可能性があるため、十分な行を選択していることを確認するために、確率を増やす必要があります。したがって、$ sizeに$ factorを掛けます(通常、$ factor = 2に設定しますが、ほとんどの場合は機能します)。最後に、limit $size
現在、問題はaccomodation_table_row_countを解決しています。テーブルサイズがわかっている場合は、テーブルサイズをハードコーディングできます。これは最も速く実行されますが、明らかにこれは理想的ではありません。Myisamを使用している場合、テーブル数の取得は非常に効率的です。私はinnodbを使用しているので、単純なカウントと選択を行っています。あなたの場合、それは次のようになります:
SELECT accomodation.ac_id,
accomodation.ac_status,
accomodation.ac_name,
accomodation.ac_status,
accomodation.ac_images
FROM accomodation, accomodation_category
WHERE accomodation.ac_status != 'draft'
AND accomodation.ac_category = accomodation_category.acat_id
AND accomodation_category.acat_slug != 'vendeglatohely'
AND ac_images != 'b:0;'
AND rand() <= $size * $factor / (select (SELECT count(*) FROM `accomodation`) * (SELECT count(*) FROM `accomodation_category`))
LIMIT $size
トリッキーな部分は、正しい確率を計算することです。次のコードを見るとわかるように、実際には一時テーブルの大まかなサイズのみが計算されます(実際には粗すぎます!)。(select (SELECT count(*) FROM accomodation) * (SELECT count(*) FROM accomodation_category))
ただし、このロジックを調整して、テーブルサイズの近似値を近似できます。行を選択するよりも、選択するのが良いことに注意してください。つまり、確率の設定が低すぎると、十分な行が選択されないおそれがあります。
テーブルサイズを再計算する必要があるため、このソリューションはQuassnoiのソリューションよりも実行速度が遅くなります。ただし、このコーディングの方がはるかに扱いやすいと思います。これは、精度+パフォーマンスとコーディングの複雑さの間のトレードオフです。そうは言っても、大きなテーブルでは、これはOrder by Rand()よりもはるかに高速です。
注:クエリロジックが許可する場合は、結合操作の前にできるだけ早くランダム選択を実行してください。