MySQL 쿼리에 끔찍한 시간을 보내고 있습니다. 나는 내 주말 대부분을 보내고 오늘이 쿼리를 좀 더 빨리 실행하려고 시도하고있다. 나는 그것을 더 빨리 만들었지 만, 내가 더 잘 만들 수 있다는 것을 안다.MySQL 쿼리 최적화 - 무작위 기록
SELECT m.id,other_fields,C.contacts_count FROM marketingDatabase AS m
LEFT OUTER JOIN
(SELECT COUNT(*) as contacts_count, rid
FROM contacts
WHERE status = 'Active' AND install_id = 'XXXX' GROUP BY rid) as C
ON C.rid = m.id
WHERE (RAND()*2612<50)
AND do_not_call != 'true'
AND `ACTUAL SALES VOLUME` >= '800000'
AND `ACTUAL SALES VOLUME` <= '1200000'
AND status = 'Pending'
AND install_id = 'XXXXX'
ORDER BY RAND()
난 'install_id', '장르'과 '상태'하지만 EXPLAIN (가)는 9100 행에 기초하여 정렬 된 표시에 인덱스를 갖는다. 설명 내
은 여기에 있습니다 : https://s3.amazonaws.com/jas-so-question/Screen+Shot+2012-03-13+at+12.34.04+AM.png
아무도 내가 조금 더 빨리이 만들기 위해 무엇을 할 수 있는지에 대한 어떤 제안이? 쿼리의 전체적인 요점은 판매량, 상태 및 do_not_call과 같은 특정 기준과 일치하는 계정 레코드 (install_id)에서 임의의 레코드를 선택하는 것입니다. 저는 현재 25 개의 레코드를 모으고 캐싱 (PHP 사용)하기 때문에 매번 25 회의 요청을 한 번만 실행해야합니다. 그러나 이미 하루에 수천 개의 요청을 처리하고 있습니다. 현재 실행하는 데 0.2 초가 걸립니다. ORDER BY RAND()를 사용하여 이미 주요 성능에 치중하고 있지만, 25 행을 정렬하는 것으로 나타났습니다.
도움을 미리 감사드립니다.
** 편집 : 'contact_sort'색인이 'contacts'테이블에 있고, 색인에 install_id, status 및 rid가 있음을 잊어 버렸습니다. (레코드 ID는 marketingDatabase에서 레코드를 참조하므로 연락처가 속한 레코드를 알 수 있습니다.
** EDIT 2 : 쿼리의 2612 숫자는 기준 (install_id, status, actual sales)과 일치하는 marketingDatabase의 행 수를 나타냅니다 볼륨 등)
http://dev.mysql.com/doc/refman/5.0/en/group-by-optimization.html을 참조하십시오. GROUP BY 및 색인을 사용할 때 발생하는 제한 사항과 복잡성이 있습니다. 매뉴얼 인용 "GROUP BY에 인덱스를 사용하기위한 가장 중요한 전제 조건은 모든 GROUP BY 컬럼이 동일한 인덱스의 속성을 참조하고 인덱스가 해당 키를 순서대로 저장한다는 것입니다 (예 : 이것은 BREE 인덱스이며 HASH가 아닙니다. 색인)." 비 인덱싱 필드로 그룹화하고 하위 쿼리에서 전체 테이블을 선택하고 순서를 지정합니다. RAND()에 의한 정렬 또한 나쁜 생각이라고 생각합니다. – fred2
ORDER BY RAND()는 매우, 매우 나쁜 아이디어입니다 (http://www.webtrenches.com/post.cfm/avoid-rand-in-mysql). – budwiser
그래, ORDER BY RAND()가 25 개의 행만 주문했기 때문에 읽었지 만 나쁜 아이디어는 아닙니다. 그렇게 큰 거래는 아닙니다. 내가 잘못? 문제를 해결하고 임의의 레코드를 얻으려면 어떻게해야합니까? 간격없이 자동 증가하는 열이 없습니다 ... 내 ID 열은 자동 증가하지만 행이 삭제 된 간격이 있습니다. – user1265617