2014-02-26 7 views
-1

제발 mysql 전문가 중 누가 하위 쿼리를 최적화하는 데 도움이 될 수 있습니까?이 복잡한 뷰 정의입니까?복잡한 MySQL 쿼리 최적화

문제는 모든 계산의 마지막 상태 (날짜순) 만 가져야한다는 것입니다. 다른 종류의 왼쪽 결합으로 변환 할 수 있습니까? 매우 느리게 진행 되었기 때문에 어떤 접근 방법을 사용해야합니까?

도움이나 조언을 주셔서 감사합니다.

CREATE VIEW admin_calculation_state_view AS SELECT 
`povruc_calculation`.`id`, 
`povruc_session`.`id` AS sessionId, 
`povruc_calculation`.`createdDate`, 
CONCAT(`povruc_calculation_subject`.`safeMonths`, '/', `povruc_calculation_subject`.`eventCount`) AS relevantTime, 
`povruc_calculation_subject`.`phone`, 
`povruc_calculation_subject`.`email`, 
`povruc_calculation_vehicle`.`manufacturer`, 
`povruc_calculation_vehicle`.`model`, 
`povruc_calculation_vehicle`.`engineDisplacement`, 
`povruc_calculation`.`priceMin`, 
`admin_user`.`username`, 
(SELECT `povruc_calculation_status`.`status` FROM `povruc_calculation_status` WHERE `povruc_calculation`.`id` = `povruc_calculation_status`.`calculation` ORDER BY `povruc_calculation_status`.`date` DESC LIMIT 1) AS lastStatus, 
(SELECT `povruc_calculation_status`.`message` FROM `povruc_calculation_status` WHERE `povruc_calculation`.`id` = `povruc_calculation_status`.`calculation` ORDER BY `povruc_calculation_status`.`date` DESC LIMIT 1) AS lastStatusMessage, 
(SELECT `povruc_calculation_statustype`.`name` FROM `povruc_calculation_status` LEFT JOIN `povruc_calculation_statustype` ON `povruc_calculation_status`.`status`=`povruc_calculation_statustype`.`id` WHERE `povruc_calculation`.`id` = `povruc_calculation_status`.`calculation` ORDER BY `povruc_calculation_status`.`date` DESC LIMIT 1) AS lastStatusName FROM `povruc_calculation` 
LEFT JOIN `povruc_calculation_subject` on `povruc_calculation_subject`.`id` = `povruc_calculation`.`subject` 
LEFT JOIN `povruc_session` on `povruc_calculation`.`session` = `povruc_session`.`id` 
LEFT JOIN `povruc_calculation_vehicle` on `povruc_calculation_vehicle`.`id` = `povruc_calculation`.`vehicle` 
LEFT JOIN `admin_user` on `povruc_calculation`.`creatorOwner` = `admin_user`.`id`; 

답변

0

상관 관계가있는 하위 쿼리를 SELECT에서 이동하고 JOIN으로 변경하면 더 효율적입니다. 이 같은

뭔가 : -

SELECT 
povruc_calculation.id, 
povruc_session.id AS sessionId, 
povruc_calculation.createdDate, 
CONCAT(povruc_calculation_subject.safeMonths, '/', povruc_calculation_subject.eventCount) AS relevantTime, 
povruc_calculation_subject.phone, 
povruc_calculation_subject.email, 
povruc_calculation_vehicle.manufacturer, 
povruc_calculation_vehicle.model, 
povruc_calculation_vehicle.engineDisplacement, 
povruc_calculation.priceMin, 
admin_user.username, 
povruc_calculation_status.status AS lastStatus, 
povruc_calculation_status.message AS lastStatusMessage, 
povruc_calculation_statustype.name AS lastStatusName 
FROM povruc_calculation 
LEFT OUTER JOIN 
(
    SELECT calculation, MAX(date) AS MaxDate 
    FROM povruc_calculation_status 
    GROUP BY calculation 
) Sub1 
ON povruc_calculation.id = Sub1.calculation 
LEFT OUTER JOIN povruc_calculation_status ON povruc_calculation_status.calculation = Sub1.calculation AND povruc_calculation_status.date = Sub1.MaxDate 
LEFT OUTER JOIN povruc_calculation_statustype ON povruc_calculation_status.status = povruc_calculation_statustype.id 
LEFT JOIN povruc_calculation_subject on povruc_calculation_subject.id = povruc_calculation.subject 
LEFT JOIN povruc_session on povruc_calculation.session = povruc_session.id 
LEFT JOIN povruc_calculation_vehicle on povruc_calculation_vehicle.id = povruc_calculation.vehicle 
LEFT JOIN admin_user on povruc_calculation.creatorOwner = admin_user.id; 

편집 - 오프 다른보기로 분할 하위 쿼리 : -이 아주 잘하지만

+0

가 답장을 보내 주셔서 감사 수행하지 않을 수 있습니다

CREATE VIEW admin_calculation_max_date AS SELECT calculation, MAX(date) AS MaxDate FROM povruc_calculation_status GROUP BY calculation; CREATE VIEW admin_calculation_state_view AS SELECT povruc_calculation.id, povruc_session.id AS sessionId, povruc_calculation.createdDate, CONCAT(povruc_calculation_subject.safeMonths, '/', povruc_calculation_subject.eventCount) AS relevantTime, povruc_calculation_subject.phone, povruc_calculation_subject.email, povruc_calculation_vehicle.manufacturer, povruc_calculation_vehicle.model, povruc_calculation_vehicle.engineDisplacement, povruc_calculation.priceMin, admin_user.username, povruc_calculation_status.status AS lastStatus, povruc_calculation_status.message AS lastStatusMessage, povruc_calculation_statustype.name AS lastStatusName FROM povruc_calculation LEFT OUTER JOIN admin_calculation_max_date Sub1 ON povruc_calculation.id = Sub1.calculation LEFT OUTER JOIN povruc_calculation_status ON povruc_calculation_status.calculation = Sub1.calculation AND povruc_calculation_status.date = Sub1.MaxDate LEFT OUTER JOIN povruc_calculation_statustype ON povruc_calculation_status.status = povruc_calculation_statustype.id LEFT JOIN povruc_calculation_subject on povruc_calculation_subject.id = povruc_calculation.subject LEFT JOIN povruc_session on povruc_calculation.session = povruc_session.id LEFT JOIN povruc_calculation_vehicle on povruc_calculation_vehicle.id = povruc_calculation.vehicle LEFT JOIN admin_user on povruc_calculation.creatorOwner = admin_user.id; 

, 이것은 내가 이미 피곤한 것이지만, 효과가 없습니다. MySQL은 "View의 SELECT에는 FROM 절의 하위 쿼리가 포함되어 있습니다." –

+0

하위 쿼리를 가져 와서 VIEW로 전환 한 다음이 쿼리를 사용하여 하위 쿼리의 조인을 새 뷰의 조인으로 대체 할 수 있다고 생각하십시오. – Kickstart

+0

글쎄, 이건 잘하고있어, 고마워. 그러나 하루가 끝나면 내 이전 솔루션보다 성능이 떨어졌습니다 (2.0 초 전의 3.0 초). 이 뷰에 대한 쿼리에서 ORDER BY 여러 열을 사용하지만 배경 테이블에서 인덱싱 되더라도 오랜 시간이 걸립니다. ORDER BY 시도해도 id. ORDER BY가 없으면 매우 빠릅니다. 편집 : 테스트하는 동안 뷰의 결과는 25,000 개가 넘습니다. –