2013-04-29 2 views
0

현재로드하는 데 시간이 오래 걸리는 SQL 쿼리가 있습니다. 누군가 도움이 될지 궁금한가요? 나는 MySQL에 대해 상당히 새로운 것이다.SQL 쿼리가 더 빠릅니다.

SELECT applicationid 
FROM logs 
WHERE action = 'VIEWED' 
AND userid = '$user' 
AND date >= '$dateminus7' 
AND applicationid NOT IN (
    SELECT applicationid 
    FROM logs 
    WHERE userid = '$user' 
    AND date >= '$dateminus7' 
    AND (action LIKE 'SUBMITTED NOTE%' OR action LIKE 'CHANGED STATUS%') 
) 

는 기본적으로 그들이 (아주 나쁜) 고객 계정에 액세스 할 때 메모를 남겨하지 않는 사용자를 찾을 일부 데이터베이스를 통해보고 :

은 쿼리입니다. 로그 데이터베이스에는 일주일에 약 30,000 개의 레코드가 있습니다. 이것은 분명히 중요한 요소이지만, 지금은 한 시간 동안 쿼리가 실행되지만 여전히 완료되지 않습니다 (시간 초과, PHP 페이지의 404 오류).

정보가 필요하다면 팁이나 안내문을 보내 주시면 감사하겠습니다.

편집 : EXPLAIN 결과 http://i.imgur.com/h9bZBe3.png

+1

테이블에 인덱스를 추가 했습니까? – Satya

+2

우리는'EXPLAIN' 문을보아야합니다. – Kermit

+0

용서해주세요, EXPLAIN 성명서는 무엇입니까? – MikeK

답변

1

(userid, date)에 종합 지수는 여기에 모두 쿼리 속도를하기에 충분해야한다. (userid, date, action) 또는 (action, userid, date)으로 시도 할 수도 있습니다. 고유 값이 더 많은 열에 따라 하나의 색인이 다른 색인보다 더 효과적 일 수 있습니다.

쿼리 플래너는 하위 쿼리를 최적화하지 못할 수도 있으며 외부 쿼리의 후보 행마다 하위 쿼리를 한 번 실행할 수도 있습니다. 내부 쿼리를 여러 번 실행하면 성능 문제가 발생할 수 있습니다. A가 대신 가입하려고 고려하고, 당신은 더 나은 성능을 얻을 수 있는지 :

SELECT la.applicationid 
FROM logs la 

LEFT OUTER JOIN logs lb 
    ON la.applicationid = lb.applicationid 
    AND lb.userid = '$user' 
    AND lb.date >= '$dateminus7' 
    AND (lb.action LIKE 'SUBMITTED NOTE%' OR lb.action LIKE 'CHANGED STATUS%') 

WHERE la.action = 'VIEWED' 
AND la.userid = '$user' 
AND la.date >= '$dateminus7' 
AND lb.applicationid IS NULL; 
+0

이것은 사용자 Barmar의 답변과 거의 비슷하므로 유망한 것으로 들리지만 내가 그에게 말했던 것처럼 SQL 결과 만 반환됩니다. '알 수없는 테이블 상태 : TABLE_TYPE'.내 '날짜'입력란에 '날짜'유형이 있는데 문제가 있습니까? 나는 내가 돌아올 것으로 기대하는 날짜 값 (OP에서 원래의 진술을 사용할 때)을 벗어난 결과를 보았을 때 그것이 될 것이라고 생각하기 시작했습니다. – MikeK

+0

그 오류는 phpmyadmin 버그 인 것 같습니다. http://stackoverflow.com/questions/2955097/information-schema-shows-unknown-table-status-table-type-mysql-phpmyadmin을 참조하십시오. – Barmar

0

내가 MySQL이 아주 잘 INNOT IN 쿼리를 최적화하지 않는 것으로 나타났습니다. 보통 JOIN으로 대체하면 상황이 개선됩니다. NOT IN를 들어 당신이 사용하는 가지고 LEFT OUTER JOIN :

SELECT l1.applicationid 
FROM logs l1 
LEFT OUTER JOIN (SELECT applicationid 
    FROM logs 
    WHERE userid = '$user' 
    AND date >= '$dateminus7' 
    AND (action LIKE 'SUBMITTED NOTE%' OR action LIKE 'CHANGED STATUS%')) l2 
ON l1.applicationid = l2.applicationid 
WHERE l1.action = 'VIEWED' 
AND l1.userid = '$user' 
AND l1.date >= '$dateminus7' 
AND l2.applicationid IS NULL 
+0

이것은 내가 어떤 날짜에 상관없이 결과를 반환하지 않습니다. 그러나 그것은 빨리 완료하는 것처럼 보입니다. 질문, 내 '날짜'필드가 '날짜'유형입니다. 이것이 문제입니까? 나는 내가 돌아올 것으로 기대하는 날짜 가치를 벗어난 결과를 보았을 때 그럴 것이라고 생각하기 시작했습니다. – MikeK

+0

작은 테스트 테이블로 쿼리를 테스트하여 작동하는지 확인 했습니까? 제 질문은 당신 생각과 같습니다. 쿼리가 완료되지 않으므로 결과를 반환한다는 것을 어떻게 알 수 있습니까? sqlfiddle.com에 작은 데이터 샘플을 게시 할 수 있습니까? – Barmar

+0

결과가 돌아 오지만 실제로는 매우 오랜 시간이 걸립니다. 궁극적으로 쿼리가 시간 초과되었지만 전에는 (PHP 페이지에서) 많은 결과가 사용자의 전반부에 나타났습니다. – MikeK

0

당신이 두 개의 "행동 = 'XXX'"두 querys에 (주 하나는 하위 쿼리)하고 그나마 지금까지 내가 생각하는 공통의 모든 기록을 가지고있다. 즉, "VIEWED"동작을 사용하는 일부 응용 프로그램을 찾고있는 경우.

SELECT가 WHERE 사용자 ID = '$ 사용자' 및 날짜> = '$의 dateminus7' AND '제출 된 참고 %'LIKE (행동 또는 조치 '변경됨와 같은 상태가 로그 로부터 을 애플리케이션 ID : 당신은 쿼리를 사용할 필요가없는 % ')

내가 놓친 것이 있는지 그리고 이것이 도움이 될지 확실하지 않습니다. 나는 이것을 따라갈 것이다.

+0

먼저, 사용자가 'VIEWED'한 모든 applicationid를 찾아야합니다. 그런 다음 해당 applicationid가 하위 쿼리에 있는지 확인해야합니다. 하위 쿼리는 동일한 사용자가 메모를 남겼는지 확인하는 것입니다 (사용자가 메모를 남기면 두 개의 다른 작업 조건이 나타납니다). 하위 쿼리에서 applicationid를 찾을 수없는 경우 메모가 남아 있지 않아 필요한 정보입니다. – MikeK

+0

@ user2332653 맑음을위한 Thx. 네가하고 싶은게있어. 하지만 혼란 스럽다는 것은 테이블 로그에있는 하나의 applicationid가 동시에 두 가지 작업을 수행 할 수 있다는 것을 의미합니까? "VIEWED"및 " 'SUBMITTED NOTE %" " – PngL

+0

예.하지만 데이터베이스에 별도의 항목 (별도의 사용자 작업이 기록됨)으로 표시됩니다. 사용자가 일부 정보를 볼 때, 정보가 기록 된 이유를 기록 할 때 기록됩니다. 기본적으로 응용 프로그램을 보는 사용자가 기록한 정보를 기록하는 이유는 무엇입니까? – MikeK

관련 문제