Tôi đã lược tả một số truy vấn trong một ứng dụng tôi đang làm việc và tôi đã truy vấn một truy vấn đang truy xuất nhiều hàng hơn mức cần thiết, tập kết quả được cắt bớt trong mã ứng dụng.Còn lại Tham gia hoạt động tốt hơn Tham gia nội bộ?
Thay đổi LEFT JOIN thành INNER JOIN đã cắt bộ kết quả thành chỉ những gì cần thiết và có lẽ sẽ có hiệu suất cao hơn (vì ít hàng hơn được chọn). Trong thực tế, truy vấn LEFT JOIN'ed đã vượt trội hơn INNER JOIN'ed, mất một nửa thời gian để hoàn thành.
LEFT JOIN: (127 tổng số hàng, Query mất 0,0011 giây)
INNER JOIN: (10 hàng tổng, Query mất 0,0024 giây)
(Tôi chạy các truy vấn nhiều lần và đó là những trung bình) .
Chạy GIẢI THÍCH trên cả hai cho thấy không có gì để giải thích sự khác biệt hiệu suất:
Đối với INNER JOIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE contacts index NULL name 302 NULL 235 Using where
1 SIMPLE lists eq_ref PRIMARY PRIMARY 4 contacts.list_id 1
1 SIMPLE lists_to_users eq_ref PRIMARY PRIMARY 8 lists.id,const 1
1 SIMPLE tags eq_ref PRIMARY PRIMARY 4 lists_to_users.tag_id 1
1 SIMPLE users eq_ref email_2 email_2 302 contacts.email 1 Using where
Đối với LEFT JOIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE contacts index NULL name 302 NULL 235 Using where
1 SIMPLE lists eq_ref PRIMARY PRIMARY 4 contacts.list_id 1
1 SIMPLE lists_to_users eq_ref PRIMARY PRIMARY 8 lists.id,const 1
1 SIMPLE tags eq_ref PRIMARY PRIMARY 4 lists_to_users.tag_id 1
1 SIMPLE users eq_ref email_2 email_2 302 contacts.email 1
Và truy vấn bản thân:
SELECT `contacts`.*, `lists`.`name` AS `group`, `lists`.`id` AS `group_id`, `lists`.`shared_yn`, `tags`.`name` AS `context`, `tags`.`id` AS `context_id`, `tags`.`color` AS `context_color`, `users`.`id` AS `user_id`, `users`.`avatar`
FROM `contacts`
LEFT JOIN `lists` ON lists.id=contacts.list_id
LEFT JOIN `lists_to_users` ON lists_to_users.list_id=lists.id AND lists_to_users.user_id='1' AND lists_to_users.creator='1'
LEFT JOIN `tags` ON tags.id=lists_to_users.tag_id
INNER JOIN `users` ON users.email=contacts.email
WHERE (contacts.user_id='1')
ORDER BY `contacts`.`name` ASC
(Điều khoản mà tôi đang nói đến là INNER JOIN cuối cùng trên bảng 'người dùng')
Truy vấn chạy trên cơ sở dữ liệu MySQL 5.1, nếu nó tạo sự khác biệt.
Có ai có manh mối về lý do truy vấn LEFT JOIN'ed hoạt động tốt hơn INNER JOIN'ed trong trường hợp này không?
CẬP NHẬT: Do đề xuất của Tomalak rằng các bảng nhỏ tôi đang sử dụng đã làm cho INNER JOIN phức tạp hơn, tôi đã tạo một cơ sở dữ liệu thử nghiệm với một số dữ liệu giả định. Bảng 'người dùng' là 5000 hàng và bảng địa chỉ liên hệ là ~ 500.000 hàng. Kết quả là như nhau (cũng là thời gian đã không thay đổi đó là đáng ngạc nhiên khi bạn xem xét rằng các bảng lớn hơn nhiều bây giờ).
Tôi cũng chạy ANALYZE và OPTIMIZE trên bảng danh bạ. Không tạo ra bất kỳ sự khác biệt rõ rệt nào.
Bạn đã thử đặt tham gia bên trong trước? –
Tôi có, nó tăng tốc truy vấn đó lên 20%, nhưng vẫn chậm hơn LEFT JOIN –
Cố gắng buil mỗi truy vấn tuần tự (tham gia một bảng, đo lường, tham gia tiếp theo, v.v.) Có thể điều này giúp bạn xác định hoạt động chậm . – Tomalak