2010-07-15 46 views
6

Query:Mysql truy vấn với Left Join là quá rất chậm

select `r`.`id` as `id` 
    from `tbl_rls` as `r` 
left join `tblc_comment_manager` as `cm` on `cm`.`rlsc_id` != `r`.`id` 

Cả hai bảng có 8k hồ sơ nhưng tại sao nó rất chậm, lấy 2-3 phút và nhiều hơn nữa đôi khi?

OMG, truy vấn này làm cho máy chủ mysql ngừng hoạt động. Sẽ lấy lại cho bạn các dân tộc trong một giây :(

Tất cả các dân tộc những gợi ý chỉ mục các cột đều đúng. Yeh truy vấn tôi đã viết là ngớ ngẩn và lỗi. Nhờ sửa tôi.

+1

Có chỉ mục nào không? Nếu vậy, trên cột nào? – middus

+1

Cả hai cột 'id' phải có chỉ mục – JohnB

Trả lời

15

cũng xem xét lập chỉ mục bảng của bạn. Chúng tôi đang chạy nhiều lần tham gia trái trên một bảng hồ sơ 1 triệu + không mất nhiều hơn một hoặc hai giây để trả lại kết quả.

+0

Chết tiệt khủng khiếp là thủ phạm này. Tôi đã đi từ 10 phút đến 0,9 ms. Bất kỳ đề xuất nào về công cụ phân tích MySQL có thể cho bạn biết bạn nên có chỉ mục nào trên cơ sở dữ liệu của mình? –

13

Bạn có thực sự cần != hoặc là nó có nghĩa là để được =?

select `r`.`id` as `id` from `tbl_rls` as `r` 
    left join `tblc_comment_manager` as `cm` 
on `cm`.`rlsc_id`!=`r`.`id 

này sẽ chọn gần sản phẩm Descartes của 2 bảng. (tôi đoán khoảng 60 triệu hàng)

Chỉnh sửa: "! =" Từ những nhận xét

có nó là để phù hợp với tbl_rls.id những người không phải trong tblc_comment_manager

Tôi nghĩ rằng đây là những gì bạn cần nếu bạn muốn sử dụng Cách tiếp cận outer join.

select DISTINCT `r`.`id` as `id` from `tbl_rls` as `r` 
    left join `tblc_comment_manager` as `cm` 
on `cm`.`rlsc_id`=`r`.`id 
WHERE `cm`.`rlsc_id` IS NULL 

Mặc dù sở thích của tôi thường là

select `r`.`id` as `id` 
from `tbl_rls` 
as `r` 
WHERE NOT EXISTS(
      SELECT * FROM `tblc_comment_manager` as `cm` 
      WHERE `cm`.`rlsc_id`=`r`.`id) 
+0

có nó là "! =" Để khớp 'tbl_rls'.'id', không có trong' tblc_comment_manager' – Arshdeep

+0

+1 để sửa truy vấn của tôi – Arshdeep

4

gì bạn muốn chọn?

Sử dụng truy vấn này nếu bạn muốn tìm tbl_rls hồ sơ chưa phù hợp với các bản ghi trong bảng khác

select `r`.`id` 
from `tbl_rls` as `r` 
left join `tblc_comment_manager` as `cm` 
    on `cm`.`rlsc_id`=`r`.`id 
where `cm`.`rlsc_id` IS NULL 
+0

+1: Bạn đã đánh bại tôi, bằng 25 giây ... –

1

Có vẻ như bạn đang muốn các giá trị r.id không nằm trong bảng tblc_comment_manager.

Sử dụng không ở

chọn r. idid
từ tbl_rlsr
nơi r. id không (chọn riêng biệt cm. rlsc_id từ tblc_comment_manager như cm)

1

MySQL của EXPLAIN có thể giúp bạn tìm hiểu những gì đang xảy ra.

2

Bạn có thể cần cung cấp thêm thông tin.Nhưng có một điều tôi sẽ cố gắng được đảo ngược thứ tự của khoản ON của bạn (bởi vì nó dễ dàng như vậy):

ON r.id != cm.rlsc_id

Edit: và bạn nên đưa chỉ số về PK của bạn (id) cột.

Nhưng tôi nghĩ this article might help you out.

Về cơ bản nó cho biết NOT IN mất ít tài nguyên hơn LEFT JOIN. Người nhận xét trong bài viết đó đề cập đến việc sử dụng NOT EXISTS là tốt nhất.

Ngoài ra, tôi không chắc điều này có chính xác hay không, nhưng this article says that NOT IN does a full table scan, and NOT EXISTS can use an index.

+1

@JohnB cho SQL Server 'NOT IN' và 'NOT EXISTS' hiệu quả hơn (mặc dù phải cẩn thận về NULLs cho cái đầu tiên). Đối với MySQL tôi không chắc chắn những gì đề nghị được. –

+0

Ngoài ra, những người khác đã chỉ ra cách tiếp cận: 'WHERE cm.rlsc_id IS NULL' – JohnB

+0

@Martin: ai đó đọc ** Hiệu suất cao MySQL ** có thể biết câu trả lời - http://www.amazon.com/High-Performance -MySQL-Jeremy-Zawodny/dp/0596003064 – JohnB