2010-07-22 2 views
2

는 매우 느립니다이 문제에 대한가져 오기 RAND() 한 쿼리 RAND() BY ORDER없는 행은 거대한 테이블에서 하나의 임의의 행을 얻기 위해 MySQL의에서 RAND()를 사용

SELECT quote FROM quotes ORDER BY RAND() LIMIT 1 

Here is an article 이것이 왜 그런지입니다. 이것은 단지 하나 개의 쿼리 가능한 지 여부,

SELECT COUNT(*) AS cnt FROM quotes 

- Use result to generate a number between 0 and COUNT(*) 

SELECT quote FROM quotes LIMIT $generated_number, 1 

궁금 :

이들 솔루션은 두 개의 쿼리를 사용하는 것입니다.

SELECT * FROM quotes 
LIMIT (
    ROUND(
    (SELECT COUNT(*) FROM quotes) * RAND() 
) 
), 1 

을하지만 MySQL이 제한 내에서 어떤 논리를 허용하지 않습니다 솔기 :

그래서 내 방식이었다. 이 주제에 관한 정보는 찾을 수 없지만 이것이 사실인지는 알 수 없습니다.

그래서 내 질문 :

  1. 어떻게 LIMIT 내에서 RAND()를 사용할 수

    ?
  2. 에 대한 다른 방법은 하나의 쿼리로 해결할 수 있습니까? quotes_id가 틈이 없을 경우

    SELECT * FROM quotes 
    WHERE quotes_id = ROUND(
        (SELECT COUNT(*) FROM quotes) * RAND() 
    ) 
    LIMIT 1 
    

    하지만에만 작동합니다 :

+0

가능한 복제본 [MySQL은 빠른 600K 행에서 10 개의 임의 행을 선택합니다.] (0120-365-006) –

+0

나중에 다른 질문이 나보다 많이 게시되었다 :-) 그것이 중복되었지만, 네. – JochenJung

답변

5

저장 프로 시저를 사용하여 준비된 문을 만들 수없는 이유가 있습니까?

DELIMITER // 
DROP PROCEDURE IF EXISTS rand_quote// 
CREATE PROCEDURE rand_quote() 
BEGIN 
    SET @rand := ROUND((SELECT COUNT(*) FROM quotes) * RAND()); 
    SET @sql := CONCAT('SELECT * FROM quotes LIMIT ', @rand, ', 1'); 
    PREPARE stmt FROM @sql; 
    EXECUTE stmt; 
    DEALLOCATE PREPARE stmt; 
END; 
// 
DELIMITER ; 
+0

멋진 생각. 코드 예제를 가져 주셔서 감사합니다. – JochenJung

1

난 그냥 솔루션과 같은 솔기가이 일을 figgured.

+0

RAND()가 난수를 생성하면 어떤 차이가 있습니까? 제 관심은 무작위 부분이 단일 값을 반환한다는 것이며 무작위 부분이 반환하는 값이 데이터에 존재하지 않을 위험이 있다는 것입니다. –

+0

그게 무슨 뜻인지 갭. 반환 된 단일 값이 해당 간격 (해당 데이터 없음)에 도달 할 수 있습니다. – JochenJung

+0

quotes_id에 기본 키인 필터가 있기 때문에 "LIMIT 1"을 사용하면 쓸모가 없습니다. 두 개 이상의 레코드를 반환하지 않습니다. – Jocelyn

1

최대 ID를 확인하여 문제를 해결했습니다. 그런 다음 객체가 존재하는지 검사하는 rand (0, max_id)의 PHP 루프를 만들었습니다. 끝난.

rand를 사용하면 훨씬 빨라 이전에 주문할 수 있습니다.