복붙노트

[SQL] 빠른 600K 행에서 10 개 임의의 행을 선택 MYSQL

SQL

빠른 600K 행에서 10 개 임의의 행을 선택 MYSQL

어떻게 가장 쿼리를 작성할 수 600K의 총 무작위로 선택 10 행?

해결법

  1. ==============================

    1.간단한에서, 틈에, 갭 균일하지 않은 몇 가지 사례를 처리하는 좋은 게시물.

    간단한에서, 틈에, 갭 균일하지 않은 몇 가지 사례를 처리하는 좋은 게시물.

    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
    

    이러한 전제로 IDS의 분포가 동일하도록, 상기 ID리스트에 갭이있을 수있다. 고급 예제 문서를 참조하십시오

  2. ==============================

    2.

    SELECT column FROM table
    ORDER BY RAND()
    LIMIT 10
    

    아니 효율적인 솔루션하지만 작품

  3. ==============================

    3.우수한 성능을 가지고 있으며, 격차와 함께 작동 간단한 쿼리 :

    우수한 성능을 가지고 있으며, 격차와 함께 작동 간단한 쿼리 :

    SELECT * FROM tbl WHERE id IN 
        (SELECT id FROM (SELECT id FROM tbl ORDER BY RAND() LIMIT 10) t)
    

    MySQL은 아직 처음에 LIMIT를 지원하지 않기 때문에 두 중첩 된 하위 쿼리가 사용됩니다.

    정렬 단계는 인덱스 ID 열을 사용하기 때문 빠릅니다.

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

  4. ==============================

    4.나는 400K 레지스터 MySQL 데이터베이스 캐시되지 않은 2 기가 바이트 크기의 10 개 임의의 행을 선택, 느린 CPU와 빠른 쿼리 (약 0.5 초)을 얻고있다. 여기에 내 코드를 참조하십시오 임의 행의 빠른 선택을 MySQL의에

    나는 400K 레지스터 MySQL 데이터베이스 캐시되지 않은 2 기가 바이트 크기의 10 개 임의의 행을 선택, 느린 CPU와 빠른 쿼리 (약 0.5 초)을 얻고있다. 여기에 내 코드를 참조하십시오 임의 행의 빠른 선택을 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);
    ?>
    
  5. ==============================

    5.그것의 매우 간단하고 단 한 줄의 쿼리.

    그것의 매우 간단하고 단 한 줄의 쿼리.

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

    6.책에서 :

    책에서 :

    띄우기 사용하여 임의의 행을 선택

    여전히 문제를 방지 다른 기술은 이전에 발견 대안은 데이터 세트의 행을 계산하고 임의을 반환하는 것입니다 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();
    

    당신이 연속 된 키 값을 추정 할 수없는 경우이 솔루션을 사용하여 당신은 반드시 각 행이 선택되는 더 기회를 확인해야합니다.

  7. ==============================

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

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

    여기에서: MySQL은 임의의 행을 선택

    "테이블 스캔"을 통해 빠른 개선은 임의의 ID를 데리러 인덱스를 사용하는 것입니다.

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

    8.당신이 당신의 키에 틈이없고 그들은 모두 숫자입니다 잘 경우 당신은 임의의 숫자를 계산하고 그 라인을 선택할 수 있습니다. 그러나 이것은 아마도 경우되지 않습니다.

    당신이 당신의 키에 틈이없고 그들은 모두 숫자입니다 잘 경우 당신은 임의의 숫자를 계산하고 그 라인을 선택할 수 있습니다. 그러나 이것은 아마도 경우되지 않습니다.

    그래서 하나 개의 솔루션은 다음과 같다 :

    SELECT * FROM table WHERE key >= FLOOR(RAND()*MAX(id)) LIMIT 1
    

    이는 기본적으로 당신이 당신의 키의 범위에서 임의의 숫자를 얻을 수 있도록 그리고 당신은 더 큰되는 차선을 선택합니다. 이 10 시간을해야한다.

    당신의 키가 가장 가능성이 고르게 분포되지 않기 때문에 그러나 이것은 정말 무작위 아닙니다.

    그것은 모든 요구 사항을 충족 해결하기 쉽지 않은 정말 큰 문제이고, MySQL은의 랜드 () 당신이 정말로 10 개 임의 행을 원하는 경우에 당신이 얻을 수있는 최선이다.

    빠른하지만 또한 임의성에 올 때 떨어져 무역을 가지고 있지만, 더 나은 서비스를 맞게 수있는 다른 해결책은 그러나이있다. 여기에 대해 읽기 : 어떻게 내가 MySQL을의 ORDER BY RAND () 함수를 최적화 할 수 있습니다?

    질문 할 당신은 그것을 필요하는 방법을 무작위입니다.

    내가 당신에게 좋은 솔루션을 제공 할 수 있도록 더 많은 비트를 설명 할 수 있습니다.

    예를 들어 내가 함께 일한 회사들은 매우 빠른 절대 임의성을 필요로하는 솔루션을했다. 그들은 나중에 다시 다른 임의의 값으로 하강하고 설정을 선택하고 임의의 값을 사용하여 데이터베이스를 미리 채우는으로 돌아가 셨습니다.

    당신은 좀처럼 당신이 틈이없고 단지 선택하기 전에 임의의 키를 계산할 수 있도록도 증가 ID를 채울 수 업데이트하지 않으면 ... 그것은 사용 사례에 따라 달라집니다!

  9. ==============================

    9.나는 오히려 큰 테이블에서 임의 많은 수의 행을 반환하는 쿼리를 필요로했다. 이것은 내가 생각 해낸 것입니다. 먼저 최대 레코드 ID를 얻을 :

    나는 오히려 큰 테이블에서 임의 많은 수의 행을 반환하는 쿼리를 필요로했다. 이것은 내가 생각 해낸 것입니다. 먼저 최대 레코드 ID를 얻을 :

    SELECT MAX(id) FROM table_name;
    

    그런 다음 그 값을로 대체 :

    SELECT * FROM table_name WHERE id > FLOOR(RAND() * max) LIMIT n;
    

    어디 최대하면 테이블의 최대 레코드 ID이고 n 당신의 결과 집합에서 원하는 행의 수입니다. 가정은 레코드 ID에 틈이 나는이 있다면이 결과에 영향을 미칠 것이라고 의심하지만 것 없다는 것입니다 (하지만 그것을 시도하지 않은). 나는 또한 더 일반적인 것으로이 저장 프로 시저를 생성; 테이블 이름과 행 수의 패스를 반환합니다. 나는 윈도우 2008 32 기가 바이트 듀얼 3GHz의 E5450에서 MySQL 5.5.38을 실행하는거야, 그리고 17,361,264 행이 테이블에 1,000,000 행을 반환하는 ~ .03 초 / ~ 11 초에서 상당히 일치합니다. (시간은 MySQL의 워크 벤치 6.1에서 있습니다, 당신은 또한 당신의 취향에 따라 2 select 문 대신 FLOOR의 CEIL를 사용할 수 있습니다)

    DELIMITER $$
    
    USE [schema name] $$
    
    DROP PROCEDURE IF EXISTS `random_rows` $$
    
    CREATE PROCEDURE `random_rows`(IN tab_name VARCHAR(64), IN num_rows INT)
    BEGIN
    
    SET @t = CONCAT('SET @max=(SELECT MAX(id) FROM ',tab_name,')');
    PREPARE stmt FROM @t;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    
    SET @t = CONCAT(
        'SELECT * FROM ',
        tab_name,
        ' WHERE id>FLOOR(RAND()*@max) LIMIT ',
        num_rows);
    
    PREPARE stmt FROM @t;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    END
    $$
    

    그때

    CALL [schema name].random_rows([table name], n);
    
  10. ==============================

    10.나는이 http://jan.kneschke.de/projects/mysql/order-by-rand/ Riedsio에 의해 게시 사용 (내가 저장 프로 시저의 경우 사용하는 반환 하나 이상의 임의 값) :

    나는이 http://jan.kneschke.de/projects/mysql/order-by-rand/ Riedsio에 의해 게시 사용 (내가 저장 프로 시저의 경우 사용하는 반환 하나 이상의 임의 값) :

       DROP TEMPORARY TABLE IF EXISTS rands;
       CREATE TEMPORARY TABLE rands ( rand_id INT );
    
        loop_me: LOOP
            IF cnt < 1 THEN
              LEAVE loop_me;
            END IF;
    
            INSERT INTO rands
               SELECT r1.id
                 FROM random AS r1 JOIN
                      (SELECT (RAND() *
                                    (SELECT MAX(id)
                                       FROM random)) AS id)
                       AS r2
                WHERE r1.id >= r2.id
                ORDER BY r1.id ASC
                LIMIT 1;
    
            SET cnt = cnt - 1;
          END LOOP loop_me;
    

    문서 그는 (... 문서 표시 등 트리거를 사용하여) 테이블을 유지함으로써 안 랜덤 결과를 초래 IDS의 갭의 문제를 해결한다; 나는 1부터 연속 번호로 채워, 테이블에 다른 열을 추가하여 문제를 해결하고 있습니다 (편집 :이 열이 영구 테이블에 영향을주지 않습니다, 런타임에 하위 쿼리에 의해 생성 된 임시 테이블에 추가됩니다)

       DROP TEMPORARY TABLE IF EXISTS rands;
       CREATE TEMPORARY TABLE rands ( rand_id INT );
    
        loop_me: LOOP
            IF cnt < 1 THEN
              LEAVE loop_me;
            END IF;
    
            SET @no_gaps_id := 0;
    
            INSERT INTO rands
               SELECT r1.id
                 FROM (SELECT id, @no_gaps_id := @no_gaps_id + 1 AS no_gaps_id FROM random) AS r1 JOIN
                      (SELECT (RAND() *
                                    (SELECT COUNT(*)
                                       FROM random)) AS id)
                       AS r2
                WHERE r1.no_gaps_id >= r2.id
                ORDER BY r1.no_gaps_id ASC
                LIMIT 1;
    
            SET cnt = cnt - 1;
          END LOOP loop_me;
    

    기사에 난 그 코드를 최적화 할 수있는 훌륭한 길이에 가서 볼 수 있습니다; 나의 변화가 성능에 영향을 미칠하지만 나를 위해 아주 잘 작동 얼마나 / 만약 내가 없습니다 ideea.

  11. ==============================

    11.여기에 많은 도움이 될 수있는 게임 체인저입니다;

    여기에 많은 도움이 될 수있는 게임 체인저입니다;

    나는 내가 테이블에서 가장 큰 ID에 기반을 임의 값을 생성하도록 선택할 수 있도록, N에게 임의의 행을 선택하는 데 필요한, 순차적 ID의로, 200K 행 테이블이, 나는 가장 빠른 작동되는 알이 스크립트를 생성 :

    logTime();
    query("SELECT COUNT(id) FROM tbl");
    logTime();
    query("SELECT MAX(id) FROM tbl");
    logTime();
    query("SELECT id FROM tbl ORDER BY id DESC LIMIT 1");
    logTime();
    

    그 결과는 다음과 같습니다

    이 결과를 바탕으로 주문 내림차순은 최대 ID를 얻을 수있는 가장 빠른 작업입니다, 여기에 질문에 대한 내 대답은 :

    SELECT GROUP_CONCAT(n SEPARATOR ',') g FROM (
        SELECT FLOOR(RAND() * (
            SELECT id FROM tbl ORDER BY id DESC LIMIT 1
        )) n FROM tbl LIMIT 10) a
    
    ...
    SELECT * FROM tbl WHERE id IN ($result);
    

    참고하십시오 200K 테이블에서 10 개 임의의 행을 얻으려면, 그것은 나에게 (PHP는 측면에서 모든 작업 포함) 1.78 밀리했다

  12. ==============================

    12.모든 최선의 답은 이미 (주로 링크 http://jan.kneschke.de/projects/mysql/order-by-rand/를 참조 할 것)에 게시되어있다.

    모든 최선의 답은 이미 (주로 링크 http://jan.kneschke.de/projects/mysql/order-by-rand/를 참조 할 것)에 게시되어있다.

    캐싱 - 나는 다른 속도 향상 가능성을 정확하게 지적하고 싶다. 당신이 임의의 행을 얻을 필요가 이유를 생각하십시오. 아마 당신은 웹 사이트에서 어떤 임의의 게시하거나 무작위 광고를 표시 할 수 있습니다. 100 REQ를 받고있는 경우 /, 그것은 정말 각 방문자 임의의 행을 얻을 것이 필요하다 s는? 보통 1 초 (또는 십초) 이러한 X 임의의 행을 캐시에 완전히 괜찮습니다. 다음 두 번째는 또 다른 100 방문자가 게시물의 다른 세트를 얻을 수 있기 때문에 같은 1 100 고유 방문자가 두 번째, 같은 임의의 게시물을 얻을 수 있다면 그것은 중요하지 않습니다.

    이 두 번째 관계없이 REQ의 번만 당 MySQL의에서 가져올 수있는 바와 같이, 사용자가 임의의 데이터를 얻기 위해 또한 느린 솔루션의 일부를 사용할 수있는이 캐싱을 사용하는 경우 / S.

  13. ==============================

    13.나는 @Riedsio 있던 대답을 개선. 이것은 내가 갭 큰, 균일하게 분포 된 테이블에서 찾을 수있는 가장 효율적인 쿼리입니다 (> 2.6B 행이있는 테이블에서 1,000 임의 행을 받고 테스트).

    나는 @Riedsio 있던 대답을 개선. 이것은 내가 갭 큰, 균일하게 분포 된 테이블에서 찾을 수있는 가장 효율적인 쿼리입니다 (> 2.6B 행이있는 테이블에서 1,000 임의 행을 받고 테스트).

    (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max := (SELECT MAX(id) FROM table)) + 1 as rand) r on id > rand LIMIT 1) UNION
    (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
    (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
    (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
    (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
    (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
    (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
    (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
    (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
    (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1)
    

    나에게 무슨 일이 일어나고 있는지 풀어 보자.

    노조를 수행하면 여러 쿼리를 수행 피할 수 있도록 한 쿼리에 모든 걸 맞는 데 도움이됩니다. 그것은 또한 당신이 MAX (ID)를 계산하는 오버 헤드를 저장할 수 있습니다. 응용 프로그램에 따라이 많이 또는 거의 문제가 있습니다.

    이 단지 ID를 얻고 무작위 순서로 얻을 수 있습니다. 당신이 더 많은 아무것도 할하려면 고급 나는이 작업을 수행하는 것이 좋습니다 :

    SELECT t.id, t.name -- etc, etc
    FROM table t
    INNER JOIN (
        (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max := (SELECT MAX(id) FROM table)) + 1 as rand) r on id > rand LIMIT 1) UNION
        (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
        (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
        (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
        (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
        (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
        (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
        (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
        (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1) UNION
        (SELECT id FROM table INNER JOIN (SELECT FLOOR(RAND() * @max) + 1 as rand) r on id > rand LIMIT 1)
    ) x ON x.id = t.id
    ORDER BY t.id
    
  14. ==============================

    14.이 슈퍼 빠른이며 격차를 경우에도 100 % 랜덤.

    이 슈퍼 빠른이며 격차를 경우에도 100 % 랜덤.

    나는 책을 빌 Karwin에서 SQL 안티 패턴이 해킹을 발견했다.

  15. ==============================

    15.(600K 그 정도되지 않습니다) 임시 테이블로 @redsio의 답을 결합 :

    (600K 그 정도되지 않습니다) 임시 테이블로 @redsio의 답을 결합 :

    DROP TEMPORARY TABLE IF EXISTS tmp_randorder;
    CREATE TABLE tmp_randorder (id int(11) not null auto_increment primary key, data_id int(11));
    INSERT INTO tmp_randorder (data_id) select id from datatable;
    

    그리고 @redsios 대답의 버전을 :

    SELECT dt.*
    FROM
           (SELECT (RAND() *
                         (SELECT MAX(id)
                            FROM tmp_randorder)) AS id)
            AS rnd
     INNER JOIN tmp_randorder rndo on rndo.id between rnd.id - 10 and rnd.id + 10
     INNER JOIN datatable AS dt on dt.id = rndo.data_id
     ORDER BY abs(rndo.id - rnd.id)
     LIMIT 1;
    

    테이블이 큰 경우에는 첫 번째 부분에 체 수 있습니다 :

    INSERT INTO tmp_randorder (data_id) select id from datatable where rand() < 0.01;
    

    이 용액을 매우 (하루에 한 번) 간격들을 재정렬 최고 및 최저 random_sortorder 갖는 '에지 로우'를 판별한다.

  16. ==============================

    16.또 다른 간단한 솔루션은 행의 순위를하고 그 중 하나를 임의로 인출이 솔루션 당신은 어떤 '아이디'테이블을 기반으로 열이 필요가 없습니다 것입니다.

    또 다른 간단한 솔루션은 행의 순위를하고 그 중 하나를 임의로 인출이 솔루션 당신은 어떤 '아이디'테이블을 기반으로 열이 필요가 없습니다 것입니다.

    SELECT d.* FROM (
    SELECT  t.*,  @rownum := @rownum + 1 AS rank
    FROM mytable AS t,
        (SELECT @rownum := 0) AS r,
        (SELECT @cnt := (SELECT RAND() * (SELECT COUNT(*) FROM mytable))) AS n
    ) d WHERE rank >= @cnt LIMIT 10;
    

    당신이 원하는대로 당신은 많은 행으로 액세스 당신의 필요에 따라 한계 값을 변경할 수 있지만 대부분은 연속적인 값이 될 것입니다.

    당신이 연속 임의의 값을 원하지 않는 경우, 당신은 더 큰 샘플을 가져올 수 있으며에서 임의로 선택합니다. 같은 ...

    SELECT * FROM (
    SELECT d.* FROM (
        SELECT  c.*,  @rownum := @rownum + 1 AS rank
        FROM buildbrain.`commits` AS c,
            (SELECT @rownum := 0) AS r,
            (SELECT @cnt := (SELECT RAND() * (SELECT COUNT(*) FROM buildbrain.`commits`))) AS rnd
    ) d 
    WHERE rank >= @cnt LIMIT 10000 
    ) t ORDER BY RAND() LIMIT 10;
    
  17. ==============================

    17.자동 생성 된 ID가 있다면 내가 꽤 좋은를 찾을 수 있다는 한 가지 방법은 나머지 연산자 '%'를 사용하는 것입니다. 당신이 70,000에서 10,000 임의 기록을 필요로하는 경우 예를 들어, 당신은 당신이 매 7 행에서 1을 필요로 말하여이 작업을 단순화 할 수 있습니다. 이것은이 쿼리에서 간단하게 할 수 있습니다 :

    자동 생성 된 ID가 있다면 내가 꽤 좋은를 찾을 수 있다는 한 가지 방법은 나머지 연산자 '%'를 사용하는 것입니다. 당신이 70,000에서 10,000 임의 기록을 필요로하는 경우 예를 들어, 당신은 당신이 매 7 행에서 1을 필요로 말하여이 작업을 단순화 할 수 있습니다. 이것은이 쿼리에서 간단하게 할 수 있습니다 :

    SELECT * FROM 
        table 
    WHERE 
        id % 
        FLOOR(
            (SELECT count(1) FROM table) 
            / 10000
        ) = 0;
    

    사용 가능한 총으로 대상 행을 분할의 결과가 정수가 아닌 경우, 당신은 당신이이 같은 결과 집합을 손질하는 데 도움이 LIMIT 절을 추가해야합니다, 그래서 당신이 요구하는 것보다 몇 가지 추가 행이있을 것이다 :

    SELECT * FROM 
        table 
    WHERE 
        id % 
        FLOOR(
            (SELECT count(1) FROM table) 
            / 10000
        ) = 0
    LIMIT 10000;
    

    이는 전체 검사를 필요로하지 않습니다,하지만 빠른 ORDER BY RAND보다, 간단 내 의견 것은이 스레드에 언급 된 다른 옵션보다 이해하기. DB를 쓰는 시스템이 일괄 적으로 행 세트를 생성 또한 경우에 기대 어디에 당신은 당신과 같은 임의의 결과를 얻을하지 않을 수 있습니다.

  18. ==============================

    18.하나 개 무작위로 기록하려는 경우 (상관없이 ID 사이에 차이가있는 경우) :

    하나 개 무작위로 기록하려는 경우 (상관없이 ID 사이에 차이가있는 경우) :

    PREPARE stmt FROM 'SELECT * FROM `table_name` LIMIT 1 OFFSET ?';
    SET @count = (SELECT
            FLOOR(RAND() * COUNT(*))
        FROM `table_name`);
    
    EXECUTE stmt USING @count;
    

    출처 : https://www.warpconduit.net/2011/03/23/selecting-a-random-record-using-mysql-benchmark-results/#comment-1266

  19. ==============================

    19.나는 모든 답변을 통해 검토 한 결과, 나는 사람이 모두에서 이러한 가능성을 언급 생각하지 않는다, 나는 확실 왜 안 해요.

    나는 모든 답변을 통해 검토 한 결과, 나는 사람이 모두에서 이러한 가능성을 언급 생각하지 않는다, 나는 확실 왜 안 해요.

    미성년자의 비용으로 최대한의 단순성과 속도를 원한다면, 나에게 DB의 각 행에 대한 임의의 숫자를 저장하는 데 의미를 보인다. 그냥 여분의 열, RANDOM_NUMBER을 만들고, RAND에의 기본 설정 (). 이 컬럼에 인덱스를 생성합니다.

    그럼 당신은 (PHP, 펄 무엇이든) 행이 코드에서 임의의 숫자를 생성하는 검색하고 열이 비교하고자 할 때.

    임의 LIMIT 1 : TBL WHERE RANDOM_NUMBER> = 화상에서 선택

    그것은 하나의 행에 대해 매우 깔끔한 있지만 영업 이익은 당신이 열 별도의 시간을 호출해야합니다 (즉시 저를 탈출 영리한 팅겨 마련) 것 질문처럼 10 행에 대해 추측

  20. ==============================

    20.다음은 빠르고 편견과 id 컬럼 독립적이어야한다. 그러나 행의 수와 일치한다 반환되는 행의 수는 요청을 보증하지 않습니다.

    다음은 빠르고 편견과 id 컬럼 독립적이어야한다. 그러나 행의 수와 일치한다 반환되는 행의 수는 요청을 보증하지 않습니다.

    SELECT *
    FROM t
    WHERE RAND() < (SELECT 10 / COUNT(*) FROM t)
    

    설명 : 100 중 10 행하고자 가정은 각 행 WHERE RAND () <0.1에 의해 달성 될 수있는가 선택할 얻는 1/10 확률을 갖는다. 이 방법은 10 개 행을 보장하지 않습니다; 하지만 실행 당 행의 쿼리가 실행되는 경우 충분한 시간 평균 수는 약 10되며 테이블의 각 행은 균등하게 선택됩니다.

  21. ==============================

    21.당신은 쉽게 한계와 임의 오프셋을 사용할 수 있습니다

    당신은 쉽게 한계와 임의 오프셋을 사용할 수 있습니다

    PREPARE stm from 'select * from table limit 10 offset ?';
    SET @total = (select count(*) from table);
    SET @_offset = FLOOR(RAND() * @total);
    EXECUTE stm using @_offset;
    

    또한과 같이 where 절을 적용 할 수 있습니다

    PREPARE stm from 'select * from table where available=true limit 10 offset ?';
    SET @total = (select count(*) from table where available=true);
    SET @_offset = FLOOR(RAND() * @total);
    EXECUTE stm using @_offset;
    

    60 행에서 테스트 (700메가바이트) 테이블 쿼리 실행은 ~ 0.016sec HDD 드라이브했다 --편집하다-- 우리가 지금처럼를 선언 한 후에 다시 오프셋 확인할 수 있습니다이를 방지하기 위해, 적은 행 (또는 어쩌면 단 1 행)을 반환하는 SELECT 문에서 발생합니다 테이블의 끝 부분에 값 가까이, 걸릴 수 있습니다 오프셋 (offset)

    SET @rows_count = 10;
    PREPARE stm from "select * from table where available=true limit ? offset ?";
    SET @total = (select count(*) from table where available=true);
    SET @_offset = FLOOR(RAND() * @total);
    SET @_offset = (SELECT IF(@total-@_offset<@rows_count,@_offset-@rows_count,@_offset));
    SET @_offset = (SELECT IF(@_offset<0,0,@_offset));
    EXECUTE stm using @rows_count,@_offset;
    
  22. ==============================

    22.나는이 쿼리를 사용합니다 :

    나는이 쿼리를 사용합니다 :

    select floor(RAND() * (SELECT MAX(key) FROM table)) from table limit 10
    

    쿼리 시간 : 0.016s

  23. ==============================

    23.이것은 내가 그것을 할 방법입니다 :

    이것은 내가 그것을 할 방법입니다 :

    select * 
    from table_with_600k_rows
    where rand() < 10/600000
    limit 10
    

    좋아 나는 쓰기에 간단하고, 다른 테이블을 필요로하지 않기 때문에, 그것은 매우 빠르게 실행하는 것입니다.

  24. ==============================

    24.테이블에서 임의의 데이터를 얻기 위해 간단한 쿼리 아래를 사용합니다.

    테이블에서 임의의 데이터를 얻기 위해 간단한 쿼리 아래를 사용합니다.

    SELECT user_firstname ,
    COUNT(DISTINCT usr_fk_id) cnt
    FROM userdetails 
    GROUP BY usr_fk_id 
    ORDER BY cnt ASC  
    LIMIT 10
    
  25. ==============================

    25.나는 이것이 최상의 방법 것 같다 ..

    나는 이것이 최상의 방법 것 같다 ..

    SELECT id, id * RAND( ) AS random_no, first_name, last_name
    FROM user
    ORDER BY random_no
    
  26. from https://stackoverflow.com/questions/4329396/mysql-select-10-random-rows-from-600k-rows-fast by cc-by-sa and MIT license