2017-07-28 21 views
6

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?

+0

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

+0

@ 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

+1

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

Trả lời

5

Kiến thức về MySQL của tôi rất hạn chế. Nhưng đây là những suy nghĩ của tôi:

Bảng của bạn không có chỉ mục. Sau đó, tham gia phải đọc toàn bộ bảng thứ hai để so sánh, cho mỗi hàng của bảng đầu tiên.

Truy vấn phụ đọc bảng thứ hai một lần và tạo chỉ mục, sau đó không cần phải đọc toàn bộ bảng thứ hai cho mỗi hàng của bảng đầu tiên. Nó chỉ phải kiểm tra chỉ mục, nhanh hơn rất nhiều.

Để xác minh xem tôi có hay không, hãy thử tạo chỉ mục cho số thứ tự cột trong hai bảng của bạn (CREATE INDEX ...) và chạy lại hai truy vấn này. Truy vấn đầu tiên của bạn chỉ mất chưa đầy một giây thay vì một phút.

+0

Là một nỗi đau để kéo dữ liệu xuống để dev của tôi để kiểm tra này, nhưng khi tôi đã làm tôi thấy rằng câu trả lời của bạn là chính xác. Cảm ơn câu trả lời, có ý nghĩa. – Goose

Các vấn đề liên quan