Tôi có hai bảng. order_details
là 100.000 hàng và outbound
là 10.000 hàng.Tại sao truy vấn tham gia đơn giản này nhanh hơn đáng kể với truy vấn phụ?
Tôi cần tham gia cùng họ trên cột có tên order_number
, đây là VARCHAR (50) trên cả hai. order_number không phải là duy nhất trong bảng đi.
CREATE TABLE `outbound` (
`outbound_id` int(12) NOT NULL,
`order_number` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `order_details` (
`order_details_id` int(12) NOT NULL,
`order_number` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Đây là câu hỏi ban đầu của tôi, và phải mất hơn 60 giây để chạy:
SELECT o.order_number
FROM outbound o
INNER JOIN order_details od
ON o.order_number = od.order_number
Truy vấn này nhận được kết quả tương tự và mất ít hơn một giây để chạy:
SELECT o.order_number
FROM outbound o
INNER JOIN
(
SELECT order_number
FROM order_details
) od
ON (o.order_number = od.order_number)
Điều này gây ngạc nhiên cho tôi vì các truy vấn phụ thường chậm hơn đáng kể.
Chạy EXPLAIN
(mà tôi vẫn đang học cách hiểu) cho thấy phiên bản truy vấn phụ sử dụng bảng derived2
, sử dụng chỉ mục và chỉ mục đó là auto_key0
. Tôi không đủ hiểu biết về cách giải thích điều này để hiểu tại sao điều này tạo nên sự khác biệt đáng kể.
Tôi đang chạy các truy vấn này qua dòng lệnh.
Tôi đang chạy MySQL Ver 14,14 Distrib 5.6.35, dành cho Linux (x86_64) CentOS.
Nói tóm lại:
Tại sao đơn giản này tham gia truy vấn nhanh hơn đáng kể với một phụ truy vấn?
Trình tối ưu hóa không hợp lệ của MySQL? Bạn có so sánh với 'EXISTS' hay' IN' không? 'CHỌN o.order_number TỪ outbound o nơi có ( CHỌN ORDER_NUMBER TỪ ORDER_DETAILS AS od ĐÂU o.order_number = od.order_number) 'hoặc' CHỌN o.order_number TỪ outbound o ĐÂU ORDER_NUMBER TRÊN ( CHỌN order_number FROM order_details ) ' – dnoeth
@ mặc dù truy vấn đầu tiên mất hơn một phút, truy vấn thứ hai đó là ngay lập tức. – Goose
Như tôi đã nói, một trình tối ưu hóa phong nha sẽ xử lý tất cả bốn điểm tương tự (trên thực tế, các kết nối có thể nhận được kết quả khác khi 'order_details.orde_number' không phải là duy nhất). – dnoeth