[mysql] MySQL은 600K 행에서 10 개의 무작위 행을 빠르게 선택합니다.

총 600k에서 무작위로 10 개의 행을 선택하는 쿼리를 작성하는 방법은 무엇입니까?



답변

간결한 간격에서 비 균일 한 간격에 이르기까지 여러 사례를 처리하는 훌륭한 포스트입니다.

http://jan.kneschke.de/projects/mysql/order-by-rand/

가장 일반적인 경우는 다음과 같습니다.

SELECT name
  FROM random AS r1 JOIN
       (SELECT CEIL(RAND() *
                     (SELECT MAX(id)
                        FROM random)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1

이것은 id의 분포가 같고 id 목록에 간격이있을 수 있다고 가정합니다. 고급 예제는 기사를 참조하십시오.


답변

SELECT column FROM table
ORDER BY RAND()
LIMIT 10

효율적인 솔루션은 아니지만 작동


답변

성능우수하고 간격 이있는 간단한 쿼리 :

SELECT * FROM tbl AS t1 JOIN (SELECT id FROM tbl ORDER BY RAND() LIMIT 10) as t2 ON t1.id=t2.id

200K 테이블에 대한이 쿼리는 0.08 초가 걸리고 일반 버전 (SELECT * FROM tbl ORDER BY RAND () LIMIT 10)은 내 컴퓨터에서 0.35 초가 걸립니다 .

정렬 단계는 색인화 된 ID 열만 사용하므로 빠릅니다. Explain에서이 동작을 볼 수 있습니다.

RAND () 제한 10을 기준으로 tbl 주문에서 선택 * :
간단한 설명

t1부터 AS t1에서 선택 * t2 ON t1.id = t2.id로 (tbl ORDER BY RAND () LIMIT 10에서 id 선택)
여기에 이미지 설명을 입력하십시오

가중 버전 : https://stackoverflow.com/a/41577458/893432


답변

나는 무엇입니까 빠른 쿼리 로 (약 0.5 초) 속도가 느린 CPU 400K 등록 MySQL 데이터베이스 캐시되지 않은 2 기가 바이트 크기의 10 개 임의의 행을 선택. 내 코드를 참조하십시오 : MySQL에서 임의의 행을 빠르게 선택 하십시오.

<?php
$time= microtime_float();

$sql='SELECT COUNT(*) FROM pages';
$rquery= BD_Ejecutar($sql);
list($num_records)=mysql_fetch_row($rquery);
mysql_free_result($rquery);

$sql="SELECT id FROM pages WHERE RAND()*$num_records<20
   ORDER BY RAND() LIMIT 0,10";
$rquery= BD_Ejecutar($sql);
while(list($id)=mysql_fetch_row($rquery)){
    if($id_in) $id_in.=",$id";
    else $id_in="$id";
}
mysql_free_result($rquery);

$sql="SELECT id,url FROM pages WHERE id IN($id_in)";
$rquery= BD_Ejecutar($sql);
while(list($id,$url)=mysql_fetch_row($rquery)){
    logger("$id, $url",1);
}
mysql_free_result($rquery);

$time= microtime_float()-$time;

logger("num_records=$num_records",1);
logger("$id_in",1);
logger("Time elapsed: <b>$time segundos</b>",1);
?>


답변

매우 간단하고 한 줄로 된 쿼리입니다.

SELECT * FROM Table_Name ORDER BY RAND() LIMIT 0,10;


답변

책에서 :

오프셋을 사용하여 임의의 행을 선택하십시오.

이전 대안에서 발견 된 문제점을 피하는 또 다른 기술은 데이터 세트의 행을 계산하고 0과 수 사이의 난수를 리턴하는 것입니다. 그런 다음 데이터 세트를 쿼리 할 때이 숫자를 오프셋으로 사용하십시오.

<?php
$rand = "SELECT ROUND(RAND() * (SELECT COUNT(*) FROM Bugs))";
$offset = $pdo->query($rand)->fetch(PDO::FETCH_ASSOC);
$sql = "SELECT * FROM Bugs LIMIT 1 OFFSET :offset";
$stmt = $pdo->prepare($sql);
$stmt->execute( $offset );
$rand_bug = $stmt->fetch();

연속 키 값을 가정 할 수없고 각 행에 고른 기회가 있는지 확인해야 할 때이 솔루션을 사용하십시오.


답변

테이블에서 임의의 행을 선택하는 방법 :

여기에서 : MySQL에서 임의의 행을 선택 하십시오.

“테이블 스캔”보다 빠른 개선은 인덱스를 사용하여 임의의 ID를 선택하는 것입니다.

SELECT *
FROM random, (
        SELECT id AS sid
        FROM random
        ORDER BY RAND( )
        LIMIT 10
    ) tmp
WHERE random.id = tmp.sid;