복붙노트

[SQL] MySQL의 큰 테이블에서 임의의 행의 빠른 선택

SQL

MySQL의 큰 테이블에서 임의의 행의 빠른 선택

큰 MySQL의 테이블에서 임의의 행을 선택하는 빠른 방법은 무엇입니까?

나는 PHP에서 일하고 있어요,하지만 난 그것을 다른 언어로 경우에도 모든 솔루션에 관심이 있어요.

해결법

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

    1.모든 아이디의 잡아 그것에서 무작위로 하나를 선택하고, 전체 행을 검색 할 수 있습니다.

    모든 아이디의 잡아 그것에서 무작위로 하나를 선택하고, 전체 행을 검색 할 수 있습니다.

    당신이 아이디의 구멍없이 순차적 알고 있다면, 당신은 단지 최대 잡고 임의의 ID를 계산할 수 있습니다.

    여기 저기 구멍이 있지만, 대부분은 순차적 인 값은, 당신은, 약간 기울어 임의성에 대한 관심 최대 값을 잡고, ID를 계산하고 ID가 첫 번째 행을 선택하지 않으면 계산 된 하나 또는 이상 동일. 비뚤어 이유는 ID의 다음과 같은 구멍이 다른 ID를 따를 것보다 포착되는 더 높은 기회를 가질 것입니다.

    당신이 무작위로 주문하는 경우에, 당신은 당신의 손에 끔찍한 테이블 스캔을 할 겁니다, 단어는 바로 이러한 솔루션에 적용되지 않습니다.

    그러지 마, 나 당신이 GUID로 주문해야, 같은 문제가 있습니다.

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

    2.나는 빠른 방법으로 하나의 쿼리에서 그것을 할 수있는 방법이있을 것을 알고 있었다. 그리고 여기있다 :

    나는 빠른 방법으로 하나의 쿼리에서 그것을 할 수있는 방법이있을 것을 알고 있었다. 그리고 여기있다 :

    외부 코드의 참여없이, 명성에 대한 빠른 방법

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

    SELECT name
      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;
    
  3. ==============================

    3.미디어 위키 (: 랜덤 기능 위키 백과의 특수에 대한) : 재미있는 트릭을 사용하는 기사와 테이블이 임의의 숫자 (기사가 작성 될 때 생성)과 여분의 열이 있습니다. 임의의 기사를 얻으려면, 임의의 숫자를 생성하고 다음으로 큰 이하로 문서를 얻을 난수 열에서 값 (이되지 리콜을). 인덱스, 이것은 매우 빠르게 할 수 있습니다. (그리고 미디어 위키는 PHP로 작성 MySQL을 위해 개발되었습니다.)

    미디어 위키 (: 랜덤 기능 위키 백과의 특수에 대한) : 재미있는 트릭을 사용하는 기사와 테이블이 임의의 숫자 (기사가 작성 될 때 생성)과 여분의 열이 있습니다. 임의의 기사를 얻으려면, 임의의 숫자를 생성하고 다음으로 큰 이하로 문서를 얻을 난수 열에서 값 (이되지 리콜을). 인덱스, 이것은 매우 빠르게 할 수 있습니다. (그리고 미디어 위키는 PHP로 작성 MySQL을 위해 개발되었습니다.)

    결과 숫자가 심하게 분산되어있는 경우이 방법은 문제가 발생할 수 있습니다; IIRC가, 이것은 당신이 그것을 당신이 현재 어떻게하는지 볼 수있는 코드를 살펴한다이 방법을하기로 결정 그렇다면, 미디어 위키에 수정되었습니다 (아마 그들은 주기적으로 난수 열을 다시 생성).

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

    4.여기에 상당히 빨리 실행하는 솔루션이다, 그리고 ID 값이 연속되는 또는 1에서 시작에 의존하지 않고 더 나은 무작위 분포를 가져옵니다.

    여기에 상당히 빨리 실행하는 솔루션이다, 그리고 ID 값이 연속되는 또는 1에서 시작에 의존하지 않고 더 나은 무작위 분포를 가져옵니다.

    SET @r := (SELECT ROUND(RAND() * (SELECT COUNT(*) FROM mytable)));
    SET @sql := CONCAT('SELECT * FROM mytable LIMIT ', @r, ', 1');
    PREPARE stmt1 FROM @sql;
    EXECUTE stmt1;
    
  5. ==============================

    5.어쩌면 당신이 뭔가를 같이 할 수있는 :

    어쩌면 당신이 뭔가를 같이 할 수있는 :

    SELECT * FROM table 
      WHERE id=
        (FLOOR(RAND() * 
               (SELECT COUNT(*) FROM table)
              )
        );
    

    이것은 당신의 ID 번호를 전혀 간격으로 순차적 가정한다.

  6. ==============================

    6.각 로우에 대한 계산 된 랜덤 값을 포함하는 열을 추가하고, 선택에 따라 하나 개의 결과로 제한 주문 절 것을 사용한다. 이것은 더 빨리 ORDER BY RANDOM () 원인 테이블 스캔을하는 것보다 밖으로 작동합니다.

    각 로우에 대한 계산 된 랜덤 값을 포함하는 열을 추가하고, 선택에 따라 하나 개의 결과로 제한 주문 절 것을 사용한다. 이것은 더 빨리 ORDER BY RANDOM () 원인 테이블 스캔을하는 것보다 밖으로 작동합니다.

    업데이트 : 당신은 여전히 ​​검색시 SELECT 문을 발행하기 전에 어떤 임의의 값을 계산해야 물론, 예를 들어,

    SELECT * FROM `foo` WHERE `foo_rand` >= {some random value} LIMIT 1
    
  7. ==============================

    7.랜드 만 쿼리 및 명령 없이는를 사용하여 임의의 행 ()을 생산하는 또 다른 방법이있다. 그것은 사용자 정의 변수를 포함한다. 테이블에서 임의의 행을 생성하는 방법을 참조하십시오

    랜드 만 쿼리 및 명령 없이는를 사용하여 임의의 행 ()을 생산하는 또 다른 방법이있다. 그것은 사용자 정의 변수를 포함한다. 테이블에서 임의의 행을 생성하는 방법을 참조하십시오

  8. ==============================

    8.테이블에서 임의의 행을 찾으려면, 필요한 제한 행 번호를 검색 할 경우에만 다음은 MySQL을 강제하기 때문에 전체 파일 정렬을 위해 ORDER BY RAND ()를 사용하지 않습니다. 이 전체 파일 정렬을 피하기 위해, 오직 where 절에 RAND () 함수를 사용합니다. 그것은 즉시 행의 필요한 수에 도달 중지됩니다. 보다 http://www.rndblog.com/how-to-select-random-rows-in-mysql/

    테이블에서 임의의 행을 찾으려면, 필요한 제한 행 번호를 검색 할 경우에만 다음은 MySQL을 강제하기 때문에 전체 파일 정렬을 위해 ORDER BY RAND ()를 사용하지 않습니다. 이 전체 파일 정렬을 피하기 위해, 오직 where 절에 RAND () 함수를 사용합니다. 그것은 즉시 행의 필요한 수에 도달 중지됩니다. 보다 http://www.rndblog.com/how-to-select-random-rows-in-mysql/

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

    9.이 표에없는 삭제 행을 할 경우, 가장 효율적인 방법은 다음과 같습니다

    이 표에없는 삭제 행을 할 경우, 가장 효율적인 방법은 다음과 같습니다

    (당신이 최소를 알고 있다면 난 그냥 건너 뛸 것)

    SELECT MIN(id) AS minId, MAX(id) AS maxId FROM table WHERE 1
    
    $randId=mt_rand((int)$row['minId'], (int)$row['maxId']);
    
    SELECT id,name,... FROM table WHERE id=$randId LIMIT 1
    
  10. ==============================

    10.주어진 테이블 (예를 들어 '단어')에서 여러 무작위 행을 선택, 우리 팀이 아름다움을 함께했다 :

    주어진 테이블 (예를 들어 '단어')에서 여러 무작위 행을 선택, 우리 팀이 아름다움을 함께했다 :

    SELECT * FROM
    `words` AS r1 JOIN 
    (SELECT  MAX(`WordID`) as wid_c FROM `words`) as tmp1
    WHERE r1.WordID >= (SELECT (RAND() * tmp1.wid_c) AS id) LIMIT n
    
  11. ==============================

    11.고전적인 "RAND () LIMIT 1 BY 테이블 ORDER FROM SELECT ID는"실제로 OK입니다.

    고전적인 "RAND () LIMIT 1 BY 테이블 ORDER FROM SELECT ID는"실제로 OK입니다.

    MySQL의 설명서에서 다음과 발췌를 참조하십시오 :

    당신이 ORDER BY와 LIMIT의 ROW_COUNT를 사용하는 경우, MySQL은 오히려 전체 결과를 정렬보다 정렬 된 결과의 첫 번째 ROW_COUNT 행을 발견했다대로 즉시 정렬이 종료됩니다.

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

    12.질서 요로 전체 검사 테이블을 할 것입니다. 최고의 당신이 선택 카운트를 할 경우 (*) 이상 0 사이의 임의의 행 = ROWNUM을 얻고 마지막 레지스트리

    질서 요로 전체 검사 테이블을 할 것입니다. 최고의 당신이 선택 카운트를 할 경우 (*) 이상 0 사이의 임의의 행 = ROWNUM을 얻고 마지막 레지스트리

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

    13.쉬운하지만 느린 방법이 될 것이다 (좀 작은 테이블에 좋은)

    쉬운하지만 느린 방법이 될 것이다 (좀 작은 테이블에 좋은)

    SELECT * from TABLE order by RAND() LIMIT 1
    
  14. ==============================

    14.의사 코드에서 :

    의사 코드에서 :

    sql "select id from table"
    store result in list
    n = random(size of list)
    sql "select * from table where id=" + list[n]
    

    이 ID는 고유 한 (주) 키를 가정합니다.

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

    15.둘 다 같은 질문을 토론 할 때 월 Kneschke하여이 링크를 살펴 또는이 SO 응답을 가져 가라. 이렇게 응답은 다양한 옵션을 통해 이동하고 필요에 따라 좋은 제안이있다. 월 모든 다양한 옵션 및 각각의 성능 특성을 통해 이동합니다. 그는 선택 MYSQL 내에서이 작업을 수행하는하여 가장 최적화 된 방법에 대해 다음과 끝 :

    둘 다 같은 질문을 토론 할 때 월 Kneschke하여이 링크를 살펴 또는이 SO 응답을 가져 가라. 이렇게 응답은 다양한 옵션을 통해 이동하고 필요에 따라 좋은 제안이있다. 월 모든 다양한 옵션 및 각각의 성능 특성을 통해 이동합니다. 그는 선택 MYSQL 내에서이 작업을 수행하는하여 가장 최적화 된 방법에 대해 다음과 끝 :

    SELECT name
      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;
    

    HTH,

    -DIP에서

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

    16.나는 SQL 새로운하지만 어떻게 PHP에서 임의의 숫자를 생성하고 사용하는 방법에 대한 좀 해요

    나는 SQL 새로운하지만 어떻게 PHP에서 임의의 숫자를 생성하고 사용하는 방법에 대한 좀 해요

    SELECT * FROM the_table WHERE primary_key >= $randNr
    

    이 표에 구멍이 문제가 해결되지 않습니다.

    그러나 여기 lassevks 제안에 트위스트입니다 :

    SELECT primary_key FROM the_table
    

    PHP에서 사용 mysql_num_rows도는 () 위의 결과에 따라 임의의 숫자를 생성 :

    SELECT * FROM the_table WHERE primary_key = rand_number
    

    보조 노트에 얼마나 느린 the_table SELECT * FROM이다 : 그 시점 mysql_data_seek에 데이터 포인터를 이동 한 후 mysql_num_rows도 ()에 기초하여 난수를 생성 (). 얼마나 느린 이것은 백만 행 말에 큰 테이블에있을 것입니다?

  17. ==============================

    17.내 ID를 순차적하지 않았다 어디 문제에 부딪쳤다. 내가이 함께했다.

    내 ID를 순차적하지 않았다 어디 문제에 부딪쳤다. 내가이 함께했다.

    SELECT * FROM products WHERE RAND()<=(5/(SELECT COUNT(*) FROM products)) LIMIT 1
    

    반환 된 행은 약 5,하지만 난 1로 제한합니다.

    다른 WHERE 절을 추가 할 경우 좀 더 흥미로운된다. 당신이 할인에 제품을 검색하고 싶은 말은.

    SELECT * FROM products WHERE RAND()<=(100/(SELECT COUNT(*) FROM pt_products)) AND discount<.2 LIMIT 1
    

    당신이 가진 것은 확실히 당신은 내가 왜 그것이를 갖는 100로 설정되어 충분한 결과를 반환하고 있는지 확인 할 위치를 할인 <더 결과와 한계를 반환하는 것이 좋습니다 수 있도록 서브 쿼리의 0.2 절, 느린 10 배이었다.

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

    18.여기 솔루션을 많이 참조하십시오. 하나 또는 두 개의 괜찮아 보이지만 다른 솔루션은 몇 가지 제약이있다. 그러나 다음과 같은 솔루션은 모든 상황에 작동합니다

    여기 솔루션을 많이 참조하십시오. 하나 또는 두 개의 괜찮아 보이지만 다른 솔루션은 몇 가지 제약이있다. 그러나 다음과 같은 솔루션은 모든 상황에 작동합니다

    select a.* from random_data a, (select max(id)*rand() randid  from random_data) b
         where a.id >= b.randid limit 1;
    

    여기서, ID가 연속 될 필요가 없습니다. 그것은 어떤 기본 키 / 독특한 / 자동 증가 열 수 있습니다. 큰 MySQL의 테이블에서 임의의 행을 선택하려면 다음 가장 빠른 방법을 참조하십시오

    감사 Zillur - www.techinfobest.com

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

    19.임의의 행을 얻기 위해 아래 쿼리를 사용

    임의의 행을 얻기 위해 아래 쿼리를 사용

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

    20.내가 행의 수를 얻기 위해 COUNT (*) 또는 MAX (ID)를 사용할 수 있도록 내 경우에는 내 표는 간격을 마련하지 않고, 기본 키, 자동 증가와 같은 ID가 있습니다.

    내가 행의 수를 얻기 위해 COUNT (*) 또는 MAX (ID)를 사용할 수 있도록 내 경우에는 내 표는 간격을 마련하지 않고, 기본 키, 자동 증가와 같은 ID가 있습니다.

    나는 가장 빠른 동작을 테스트하기 위해이 스크립트를했다 :

    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();
    

    그 결과는 다음과 같습니다

    주문 방법 답변 :

    SELECT FLOOR(RAND() * (
        SELECT id FROM tbl ORDER BY id DESC LIMIT 1
    )) n FROM tbl LIMIT 1
    
    ...
    SELECT * FROM tbl WHERE id = $result;
    
  21. ==============================

    21.나는 이것을 사용하고 작업이 이루어졌다 여기에서 참조

    나는 이것을 사용하고 작업이 이루어졌다 여기에서 참조

    SELECT * FROM myTable WHERE RAND()<(SELECT ((30/COUNT(*))*10) FROM myTable) ORDER BY RAND() LIMIT 30;
    
  22. ==============================

    22.가장 가능성이 가장 좋은 대답 여기에 가장 빠른 대답이 할 수있는 기능을 만들기!

    가장 가능성이 가장 좋은 대답 여기에 가장 빠른 대답이 할 수있는 기능을 만들기!

    프로 - 작품도 간격으로 매우 빠르게.

    <?
    
    $sqlConnect = mysqli_connect('localhost','username','password','database');
    
    function rando($data,$find,$max = '0'){
       global $sqlConnect; // Set as mysqli connection variable, fetches variable outside of function set as GLOBAL
       if($data == 's1'){
         $query = mysqli_query($sqlConnect, "SELECT * FROM `yourtable` ORDER BY `id` DESC LIMIT {$find},1");
    
         $fetched_data = mysqli_fetch_assoc($query);
          if(mysqli_num_rows($fetched_data>0){
           return $fetch_$data;
          }else{
           rando('','',$max); // Start Over the results returned nothing
          }
       }else{
         if($max != '0'){
            $irand = rand(0,$max); 
            rando('s1',$irand,$max); // Start rando with new random ID to fetch
         }else{
    
            $query = mysqli_query($sqlConnect, "SELECT `id` FROM `yourtable` ORDER BY `id` DESC LIMIT 0,1");
            $fetched_data = mysqli_fetch_assoc($query);
            $max = $fetched_data['id'];
            $irand = rand(1,$max);
            rando('s1',$irand,$max); // Runs rando against the random ID we have selected if data exist will return
         }
       }
     }
    
     $your_data = rando(); // Returns listing data for a random entry as a ASSOC ARRAY
    ?>
    

    테스트하지만, 심지어 격차로 임의 항목을 반환하는 작업 개념되지 않은만큼 긴 간격은로드 시간 문제를 일으킬 수있는 큰만큼이 아니기 때문에 .. 마음에이 코드를 보관하십시오.

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

    23.

    SET @COUNTER=SELECT COUNT(*) FROM your_table;
    
    SELECT PrimaryKey
    FROM your_table
    LIMIT 1 OFFSET (RAND() * @COUNTER);
    

    최초 질의의 복잡성 MyISAM 테이블에 대한 O (1)이다.

    두 번째 쿼리는 테이블 전체 검사를 함께 제공됩니다. 복잡도 = O (N)

    이 목적만을위한 별도의 테이블을 유지합니다. 원래 테이블에 삽입 할 때마다 당신은 또한이 테이블에 동일한 행을 삽입해야한다. 가정 : 없음 삭제합니다.

    CREATE TABLE Aux(
      MyPK INT AUTO_INCREMENT,
      PrimaryKey INT
    );
    
    SET @MaxPK = (SELECT MAX(MyPK) FROM Aux);
    SET @RandPK = CAST(RANDOM() * @MaxPK, INT)
    SET @PrimaryKey = (SELECT PrimaryKey FROM Aux WHERE MyPK = @RandPK);
    

    건의 DELETE가 허용하는 경우,

    SET @delta = CAST(@RandPK/10, INT);
    
    SET @PrimaryKey = (SELECT PrimaryKey
                       FROM Aux
                       WHERE MyPK BETWEEN @RandPK - @delta AND @RandPK + @delta
                       LIMIT 1);
    

    전체 복잡도는 O (1)이다.

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

    24.yourTable FROM SELECT DISTINCT WHERE * 4 = 4 LIMIT 1;

    yourTable FROM SELECT DISTINCT WHERE * 4 = 4 LIMIT 1;

  25. from https://stackoverflow.com/questions/211329/quick-selection-of-a-random-row-from-a-large-table-in-mysql by cc-by-sa and MIT license