Đầu tiên, giả sử đó (id)
là khóa chính của bảng. Trong trường hợp này, có, các phép nối là (có thể được chứng minh) dư thừa và có thể được loại bỏ.
Bây giờ đó chỉ là lý thuyết - hay toán học. Để trình tối ưu hóa thực hiện loại bỏ thực tế, lý thuyết phải được chuyển đổi thành mã và được thêm vào trong bộ tối ưu hóa / viết lại / loại bỏ tối ưu hóa. Để điều đó xảy ra, các nhà phát triển (DBMS) phải nghĩ rằng nó sẽ mang lại lợi ích tốt cho hiệu quả và đó là trường hợp đủ phổ biến.
Cá nhân, nó không giống như một (đủ phổ biến). Truy vấn - như bạn thừa nhận - trông khá ngớ ngẩn và người đánh giá không nên để nó vượt qua đánh giá, trừ khi nó được cải thiện và tham gia dự phòng bị xóa.
Điều đó nói rằng, có những truy vấn tương tự trong đó việc loại bỏ xảy ra. Có một bài đăng blog liên quan rất hay của Rob Farley: THAM GIA đơn giản hóa trong SQL Server .
Trong trường hợp của chúng tôi, tất cả những gì chúng tôi phải làm để thay đổi các phép nối thành LEFT
tham gia. Xem dbfiddle.uk . Trình tối ưu hóa trong trường hợp này biết rằng phép nối có thể được gỡ bỏ một cách an toàn mà không thể thay đổi kết quả. (Logic đơn giản hóa khá chung chung và không đặc biệt cho việc tự tham gia.)
Trong truy vấn ban đầu tất nhiên, loại bỏ các phép INNER
nối cũng không thể thay đổi kết quả. Nhưng việc tự tham gia vào khóa chính không phổ biến vì vậy trình tối ưu hóa không được thực hiện trong trường hợp này. Tuy nhiên, việc tham gia (hoặc tham gia trái) trong đó cột tham gia là khóa chính của một trong các bảng (và thường có ràng buộc khóa ngoài). Điều này dẫn đến một tùy chọn thứ hai để loại bỏ các phép nối: Thêm một ràng buộc khóa ngoài (tự tham chiếu!):
ALTER TABLE "Table"
ADD FOREIGN KEY (id) REFERENCES "Table" (id) ;
Và voila, các tham gia được loại bỏ! (đã thử nghiệm trong cùng một câu đố): tại đây
create table docs
(id int identity primary key,
doc varchar(64)
) ;
GO
✓
insert
into docs (doc)
values ('Enter one batch per field, don''t use ''GO''')
, ('Fields grow as you type')
, ('Use the [+] buttons to add more')
, ('See examples below for advanced usage')
;
GO
4 hàng bị ảnh hưởng
--------------------------------------------------------------------------------
-- Or use XML to see the visual representation, thanks to Justin Pealing and
-- his library: https://github.com/JustinPealing/html-query-plan
--------------------------------------------------------------------------------
set statistics xml on;
select d1.* from docs d1
join docs d2 on d2.id=d1.id
join docs d3 on d3.id=d1.id
join docs d4 on d4.id=d1.id;
set statistics xml off;
GO
id | tài liệu
-: | : ----------------------------------------
1 | Nhập một lô cho mỗi trường, không sử dụng 'GO'
2 | Các lĩnh vực phát triển khi bạn gõ
3 | Sử dụng các nút [+] để thêm nhiều hơn
4 | Xem các ví dụ dưới đây để sử dụng nâng cao
--------------------------------------------------------------------------------
-- Or use XML to see the visual representation, thanks to Justin Pealing and
-- his library: https://github.com/JustinPealing/html-query-plan
--------------------------------------------------------------------------------
set statistics xml on;
select d1.* from docs d1
left join docs d2 on d2.id=d1.id
left join docs d3 on d3.id=d1.id
left join docs d4 on d4.id=d1.id;
set statistics xml off;
GO
id | tài liệu
-: | : ----------------------------------------
1 | Nhập một lô cho mỗi trường, không sử dụng 'GO'
2 | Các lĩnh vực phát triển khi bạn gõ
3 | Sử dụng các nút [+] để thêm nhiều hơn
4 | Xem các ví dụ dưới đây để sử dụng nâng cao
alter table docs
add foreign key (id) references docs (id) ;
GO
✓
--------------------------------------------------------------------------------
-- Or use XML to see the visual representation, thanks to Justin Pealing and
-- his library: https://github.com/JustinPealing/html-query-plan
--------------------------------------------------------------------------------
set statistics xml on;
select d1.* from docs d1
join docs d2 on d2.id=d1.id
join docs d3 on d3.id=d1.id
join docs d4 on d4.id=d1.id;
set statistics xml off;
GO
id | tài liệu
-: | : ----------------------------------------
1 | Nhập một lô cho mỗi trường, không sử dụng 'GO'
2 | Các lĩnh vực phát triển khi bạn gõ
3 | Sử dụng các nút [+] để thêm nhiều hơn
4 | Xem các ví dụ dưới đây để sử dụng nâng cao