Nhìn vào kế hoạch EXPLAIN
của truy vấn, làm cách nào để xác định nơi tối ưu hóa tốt nhất có thể được thực hiện?Cách tối ưu hóa truy vấn MySQL dựa trên kế hoạch GIẢI THÍCH
Tôi đánh giá cao rằng một trong những điều đầu tiên cần kiểm tra là liệu các chỉ mục tốt có đang được sử dụng hay không, nhưng ngoài ra, tôi hơi bối rối. Qua thử thách và sai lầm trong quá khứ, đôi khi tôi thấy rằng thứ tự mà việc tham gia được tiến hành có thể là một nguồn cải tiến tốt, nhưng làm sao người ta có thể xác định rằng khi nhìn vào kế hoạch thực hiện?
Mặc dù tôi rất muốn hiểu rõ về cách tối ưu hóa các truy vấn (gợi ý đọc nhiều đánh giá!), Tôi cũng nhận ra rằng việc thảo luận các trường hợp cụ thể thường dễ hơn là nói tóm tắt. Vì tôi hiện đang đập đầu tôi vào tường với một này, suy nghĩ của bạn sẽ được nhiều đánh giá cao:
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE S const PRIMARY,l,p,f4 PRIMARY 2 const 1 Using temporary 1 SIMPLE Q ref PRIMARY,S S 2 const 204 Using index 1 SIMPLE V ref PRIMARY,n,Q Q 5 const,db.Q.QID 6 Using where; Using index; Distinct 1 SIMPLE R1 ref PRIMARY,L L 154 const,db.V.VID 447 Using index; Distinct 1 SIMPLE W eq_ref PRIMARY,w PRIMARY 5 const,db.R.RID,const 1 Using where; Distinct 1 SIMPLE R2 eq_ref PRIMARY,L PRIMARY 156 const,db.W.RID,const 1 Using where; Distinct
Am I correct trong việc giải thích dòng cuối cùng của kế hoạch thực hiện như sau:
- như nó được khớp hoàn toàn trên khóa chính của nó, chỉ cần một hàng của
R2
được tìm nạp trên mỗi hàng đầu ra; Tuy nhiên, - tuy nhiên, các hàng đầu ra như vậy sau đó được lọc dựa trên một số tiêu chí áp dụng cho
R2
?
Nếu vậy, sự cố của tôi nằm trong quá trình lọc xảy ra ở bước cuối cùng đó. Nếu điều kiện không dẫn đến lọc (ví dụ: WHERE `Col_1_to_3` IN (1,2,3)
), truy vấn sẽ chạy cực nhanh (~ 50ms); tuy nhiên, nếu điều kiện hạn chế các hàng được chọn (WHERE `Col_1_to_3` IN (1,2)
), truy vấn sẽ mất nhiều thời gian hơn (~ 5s). Nếu hạn chế là một trận đấu đơn lẻ (WHERE `Col_1_to_3` IN (1)
), trình tối ưu hóa đề xuất một kế hoạch thực hiện hoàn toàn khác (hoạt động tốt hơn 5 lần, nhưng vẫn còn tồi tệ hơn 50ms). Nó không có vẻ như là có một chỉ số tốt hơn có thể được sử dụng trên bảng đó (cho nó đã hoàn toàn bằng cách sử dụng khóa chính để trả về một hàng cho mỗi kết quả?).
Làm cách nào để giải thích tất cả thông tin này? Tôi có đoán được điều đó không, bởi vì việc lọc đầu ra như vậy đang diễn ra trên bảng cuối cùng để được tham gia, nỗ lực đáng kể bị lãng phí so với việc gia nhập bảng trước đó và lọc các hàng như vậy sớm hơn? Nếu vậy, làm thế nào để xác định khi nào trong kế hoạch thực hiện R2
nên được tham gia?
Trong khi tôi phản đối bao gồm các lược đồ truy vấn & đầy đủ ở đây (như tôi sẽ thực sự có khả năng biết phải tìm kiếm, không chỉ đơn thuần được cho biết câu trả lời), tôi hiểu đó là cần thiết để thúc đẩy các cuộc thảo luận:
SELECT DISTINCT
`Q`.`QID`
FROM
`S`
NATURAL JOIN `Q`
NATURAL JOIN `V`
NATURAL JOIN `R` AS `R1`
NATURAL JOIN `W`
JOIN `R` AS `R2` ON (
`R2`.`SID` = `S`.`SID`
AND `R2`.`RID` = `R1`.`RID`
AND `R2`.`VID` = `S`.`V_id`
AND `R2`.`Col_1_to_3` IN (1,2) -- this is where performance suffers!
)
WHERE
AND `S`.`SID` = @x
AND `W`.`WID` = @y
;
định nghĩa của bảng R
là:
CREATE TABLE `R` (
`SID` smallint(6) unsigned NOT NULL,
`RID` smallint(6) unsigned NOT NULL,
`VID` varchar(50) NOT NULL DEFAULT '',
`Col_1_to_3` smallint(1) DEFAULT NULL,
`T` varchar(255) DEFAULT NULL,
PRIMARY KEY (`SID`,`RID`,`VID`),
KEY `L` (`SID`,`VID`,`Col_1_to_3`),
CONSTRAINT `R_f1` FOREIGN KEY (`SID`) REFERENCES `S` (`SID`),
CONSTRAINT `R_f2` FOREIGN KEY (`SID`, `VID`) REFERENCES `V` (`SID`, `VID`),
CONSTRAINT `R_f3` FOREIGN KEY (`SID`, `VID`, `Col_1_to_3`) REFERENCES `L` (`SID`, `VID`, `LID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Bạn cũng có phiền khi hiển thị truy vấn không? –
@MarcusAdams: Tôi không * quan tâm *, nhưng bạn sẽ tìm kiếm điều gì? Tôi cảm thấy rằng tôi có khả năng tìm hiểu thêm nếu tôi biết bạn đang xem cái gì ... – eggyal
Bạn tham khảo col_1_to_3, nhưng tôi không thấy một cột như vậy trong kết quả GIẢI THÍCH. Nếu bạn có thể cụm từ câu hỏi để nó chỉ là về giải thích, nói cách khác loại bỏ các đoạn nói về truy vấn, sau đó chúng ta không cần truy vấn, và câu trả lời là có. Nói chung, chúng tôi cần truy vấn, lược đồ và giải thích, nếu không chúng tôi sẽ đoán. –