내 프로젝트에서 많은 기존 쿼리를 최적화하고 있습니다. 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를 사용하고 있기 때문에 간단한 count + selection을하고 있습니다. 귀하의 경우에는 다음과 같습니다.
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 ()보다 훨씬 빠릅니다.
참고 : 쿼리 논리가 허용하는 경우 조인 작업 전에 가능한 한 빨리 임의 선택을 수행하십시오.