[SQL] MySQL의 큰 테이블에서 임의의 행의 빠른 선택
SQLMySQL의 큰 테이블에서 임의의 행의 빠른 선택
큰 MySQL의 테이블에서 임의의 행을 선택하는 빠른 방법은 무엇입니까?
나는 PHP에서 일하고 있어요,하지만 난 그것을 다른 언어로 경우에도 모든 솔루션에 관심이 있어요.
해결법
-
==============================
1.모든 아이디의 잡아 그것에서 무작위로 하나를 선택하고, 전체 행을 검색 할 수 있습니다.
모든 아이디의 잡아 그것에서 무작위로 하나를 선택하고, 전체 행을 검색 할 수 있습니다.
당신이 아이디의 구멍없이 순차적 알고 있다면, 당신은 단지 최대 잡고 임의의 ID를 계산할 수 있습니다.
여기 저기 구멍이 있지만, 대부분은 순차적 인 값은, 당신은, 약간 기울어 임의성에 대한 관심 최대 값을 잡고, ID를 계산하고 ID가 첫 번째 행을 선택하지 않으면 계산 된 하나 또는 이상 동일. 비뚤어 이유는 ID의 다음과 같은 구멍이 다른 ID를 따를 것보다 포착되는 더 높은 기회를 가질 것입니다.
당신이 무작위로 주문하는 경우에, 당신은 당신의 손에 끔찍한 테이블 스캔을 할 겁니다, 단어는 바로 이러한 솔루션에 적용되지 않습니다.
그러지 마, 나 당신이 GUID로 주문해야, 같은 문제가 있습니다.
-
==============================
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.미디어 위키 (: 랜덤 기능 위키 백과의 특수에 대한) : 재미있는 트릭을 사용하는 기사와 테이블이 임의의 숫자 (기사가 작성 될 때 생성)과 여분의 열이 있습니다. 임의의 기사를 얻으려면, 임의의 숫자를 생성하고 다음으로 큰 이하로 문서를 얻을 난수 열에서 값 (이되지 리콜을). 인덱스, 이것은 매우 빠르게 할 수 있습니다. (그리고 미디어 위키는 PHP로 작성 MySQL을 위해 개발되었습니다.)
미디어 위키 (: 랜덤 기능 위키 백과의 특수에 대한) : 재미있는 트릭을 사용하는 기사와 테이블이 임의의 숫자 (기사가 작성 될 때 생성)과 여분의 열이 있습니다. 임의의 기사를 얻으려면, 임의의 숫자를 생성하고 다음으로 큰 이하로 문서를 얻을 난수 열에서 값 (이되지 리콜을). 인덱스, 이것은 매우 빠르게 할 수 있습니다. (그리고 미디어 위키는 PHP로 작성 MySQL을 위해 개발되었습니다.)
결과 숫자가 심하게 분산되어있는 경우이 방법은 문제가 발생할 수 있습니다; IIRC가, 이것은 당신이 그것을 당신이 현재 어떻게하는지 볼 수있는 코드를 살펴한다이 방법을하기로 결정 그렇다면, 미디어 위키에 수정되었습니다 (아마 그들은 주기적으로 난수 열을 다시 생성).
-
==============================
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.어쩌면 당신이 뭔가를 같이 할 수있는 :
어쩌면 당신이 뭔가를 같이 할 수있는 :
SELECT * FROM table WHERE id= (FLOOR(RAND() * (SELECT COUNT(*) FROM table) ) );
이것은 당신의 ID 번호를 전혀 간격으로 순차적 가정한다.
-
==============================
6.각 로우에 대한 계산 된 랜덤 값을 포함하는 열을 추가하고, 선택에 따라 하나 개의 결과로 제한 주문 절 것을 사용한다. 이것은 더 빨리 ORDER BY RANDOM () 원인 테이블 스캔을하는 것보다 밖으로 작동합니다.
각 로우에 대한 계산 된 랜덤 값을 포함하는 열을 추가하고, 선택에 따라 하나 개의 결과로 제한 주문 절 것을 사용한다. 이것은 더 빨리 ORDER BY RANDOM () 원인 테이블 스캔을하는 것보다 밖으로 작동합니다.
업데이트 : 당신은 여전히 검색시 SELECT 문을 발행하기 전에 어떤 임의의 값을 계산해야 물론, 예를 들어,
SELECT * FROM `foo` WHERE `foo_rand` >= {some random value} LIMIT 1
-
==============================
7.랜드 만 쿼리 및 명령 없이는를 사용하여 임의의 행 ()을 생산하는 또 다른 방법이있다. 그것은 사용자 정의 변수를 포함한다. 테이블에서 임의의 행을 생성하는 방법을 참조하십시오
랜드 만 쿼리 및 명령 없이는를 사용하여 임의의 행 ()을 생산하는 또 다른 방법이있다. 그것은 사용자 정의 변수를 포함한다. 테이블에서 임의의 행을 생성하는 방법을 참조하십시오
-
==============================
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.이 표에없는 삭제 행을 할 경우, 가장 효율적인 방법은 다음과 같습니다
이 표에없는 삭제 행을 할 경우, 가장 효율적인 방법은 다음과 같습니다
(당신이 최소를 알고 있다면 난 그냥 건너 뛸 것)
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.주어진 테이블 (예를 들어 '단어')에서 여러 무작위 행을 선택, 우리 팀이 아름다움을 함께했다 :
주어진 테이블 (예를 들어 '단어')에서 여러 무작위 행을 선택, 우리 팀이 아름다움을 함께했다 :
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.고전적인 "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.질서 요로 전체 검사 테이블을 할 것입니다. 최고의 당신이 선택 카운트를 할 경우 (*) 이상 0 사이의 임의의 행 = ROWNUM을 얻고 마지막 레지스트리
질서 요로 전체 검사 테이블을 할 것입니다. 최고의 당신이 선택 카운트를 할 경우 (*) 이상 0 사이의 임의의 행 = ROWNUM을 얻고 마지막 레지스트리
-
==============================
13.쉬운하지만 느린 방법이 될 것이다 (좀 작은 테이블에 좋은)
쉬운하지만 느린 방법이 될 것이다 (좀 작은 테이블에 좋은)
SELECT * from TABLE order by RAND() LIMIT 1
-
==============================
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.둘 다 같은 질문을 토론 할 때 월 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.나는 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.내 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.여기 솔루션을 많이 참조하십시오. 하나 또는 두 개의 괜찮아 보이지만 다른 솔루션은 몇 가지 제약이있다. 그러나 다음과 같은 솔루션은 모든 상황에 작동합니다
여기 솔루션을 많이 참조하십시오. 하나 또는 두 개의 괜찮아 보이지만 다른 솔루션은 몇 가지 제약이있다. 그러나 다음과 같은 솔루션은 모든 상황에 작동합니다
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.임의의 행을 얻기 위해 아래 쿼리를 사용
임의의 행을 얻기 위해 아래 쿼리를 사용
SELECT user_firstname , COUNT(DISTINCT usr_fk_id) cnt FROM userdetails GROUP BY usr_fk_id ORDER BY cnt ASC LIMIT 1
-
==============================
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.나는 이것을 사용하고 작업이 이루어졌다 여기에서 참조
나는 이것을 사용하고 작업이 이루어졌다 여기에서 참조
SELECT * FROM myTable WHERE RAND()<(SELECT ((30/COUNT(*))*10) FROM myTable) ORDER BY RAND() LIMIT 30;
-
==============================
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.
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.yourTable FROM SELECT DISTINCT WHERE * 4 = 4 LIMIT 1;
yourTable FROM SELECT DISTINCT WHERE * 4 = 4 LIMIT 1;
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
'SQL' 카테고리의 다른 글
[SQL] 날짜를 삽입하는 동안 문자열에서 날짜 및 / 또는 시간을 변환 할 때 변환 실패 (0) | 2020.03.12 |
---|---|
[SQL] 단순히 PostgreSQL의 테이블 이름을 사용할 수 없습니다 ( "관계가 존재하지 않습니다") (7) | 2020.03.12 |
[SQL] MySQL의 삽입 어디 쿼리 (0) | 2020.03.12 |
[SQL] SQL에서 단일 및 이중 따옴표의 차이점은 무엇입니까? (0) | 2020.03.12 |
[SQL] 왼쪽, 오른쪽, 외부 및 내부 조인의 차이점은 무엇입니까? (0) | 2020.03.12 |