Hiệu suất INNER THAM GIA vs LEFT THAM GIA trong SQL Server


259

Tôi đã tạo lệnh SQL sử dụng INNER THAM GIA trên 9 bảng, dù sao lệnh này mất nhiều thời gian (hơn năm phút). Vì vậy, dân gian của tôi đề nghị tôi thay đổi INNER THAM GIA thành TRÁI PHIẾU vì hiệu suất của LEFT THAM GIA tốt hơn, bất chấp những gì tôi biết. Sau khi tôi thay đổi nó, tốc độ truy vấn đã được cải thiện đáng kể.

Tôi muốn biết tại sao LEFT THAM GIA nhanh hơn INNER THAM GIA?

Lệnh SQL của tôi trông như dưới đây: SELECT * FROM A INNER JOIN B ON ... INNER JOIN C ON ... INNER JOIN Dvân vân

Cập nhật: Đây là tóm tắt về lược đồ của tôi.

FROM sidisaleshdrmly a -- NOT HAVE PK AND FK
    INNER JOIN sidisalesdetmly b -- THIS TABLE ALSO HAVE NO PK AND FK
        ON a.CompanyCd = b.CompanyCd 
           AND a.SPRNo = b.SPRNo 
           AND a.SuffixNo = b.SuffixNo 
           AND a.dnno = b.dnno
    INNER JOIN exFSlipDet h -- PK = CompanyCd, FSlipNo, FSlipSuffix, FSlipLine
        ON a.CompanyCd = h.CompanyCd
           AND a.sprno = h.AcctSPRNo
    INNER JOIN exFSlipHdr c -- PK = CompanyCd, FSlipNo, FSlipSuffix
        ON c.CompanyCd = h.CompanyCd
           AND c.FSlipNo = h.FSlipNo 
           AND c.FSlipSuffix = h.FSlipSuffix 
    INNER JOIN coMappingExpParty d -- NO PK AND FK
        ON c.CompanyCd = d.CompanyCd
           AND c.CountryCd = d.CountryCd 
    INNER JOIN coProduct e -- PK = CompanyCd, ProductSalesCd
        ON b.CompanyCd = e.CompanyCd
           AND b.ProductSalesCd = e.ProductSalesCd 
    LEFT JOIN coUOM i -- PK = UOMId
        ON h.UOMId = i.UOMId 
    INNER JOIN coProductOldInformation j -- PK = CompanyCd, BFStatus, SpecCd
        ON a.CompanyCd = j.CompanyCd
            AND b.BFStatus = j.BFStatus
            AND b.ProductSalesCd = j.ProductSalesCd
    INNER JOIN coProductGroup1 g1 -- PK = CompanyCd, ProductCategoryCd, UsedDepartment, ProductGroup1Cd
        ON e.ProductGroup1Cd  = g1.ProductGroup1Cd
    INNER JOIN coProductGroup2 g2 -- PK = CompanyCd, ProductCategoryCd, UsedDepartment, ProductGroup2Cd
        ON e.ProductGroup1Cd  = g2.ProductGroup1Cd

1
Bạn có dự án bất kỳ thuộc tính từ coUOM? Nếu không bạn có thể sử dụng một bán tham gia. Nếu có, bạn sẽ có thể sử dụng UNIONnhư là một thay thế. Chỉ đăng FROMđiều khoản của bạn là thông tin không đầy đủ ở đây.
onedaywhen

1
Tôi đã tự hỏi điều này rất thường xuyên (bởi vì tôi thấy tất cả thời gian).
Paul Draper

1
Bạn đã bỏ lỡ một Đơn đặt hàng trong lược đồ ngắn gọn của bạn? Gần đây tôi đã phải đối mặt với một vấn đề trong đó việc thay đổi INNER THAM GIA thành LEFT OUTER THAM GIA tăng tốc truy vấn từ 3 phút lên 10 giây. Nếu bạn thực sự có Order By trong truy vấn của mình, tôi sẽ giải thích thêm dưới dạng câu trả lời. Có vẻ như tất cả các câu trả lời không thực sự giải thích trường hợp mà tôi phải đối mặt.
Phuah Yee Keat

Câu trả lời:


403

A LEFT JOINhoàn toàn không nhanh hơn an INNER JOIN. Trong thực tế, nó chậm hơn; theo định nghĩa, một phép nối ngoài ( LEFT JOINhoặc RIGHT JOIN) phải thực hiện tất cả các công việc INNER JOINcộng với công việc phụ của null - mở rộng kết quả. Nó cũng sẽ được dự kiến ​​sẽ trả lại nhiều hàng hơn, tăng thêm tổng thời gian thực hiện đơn giản do kích thước lớn hơn của tập kết quả.

(Và thậm chí nếu một LEFT JOIN nhanh hơn trong cụ thể các tình huống do một số khó khăn để tưởng tượng ngã ba yếu tố, nó không phải là chức năng tương đương với một INNER JOIN, vì vậy bạn có thể không chỉ đơn giản là đi thay thế tất cả các trường hợp của một với người khác!)

Nhiều khả năng các vấn đề về hiệu suất của bạn nằm ở nơi khác, chẳng hạn như không có khóa ứng viên hoặc khóa ngoại được lập chỉ mục đúng. 9 bảng là khá nhiều để tham gia vì vậy sự chậm lại theo nghĩa đen có thể là gần như bất cứ nơi nào. Nếu bạn đăng lược đồ của mình, chúng tôi có thể cung cấp thêm chi tiết.


Biên tập:

Suy nghĩ sâu hơn về điều này, tôi có thể nghĩ về một tình huống trong đó một tình huống LEFT JOINcó thể nhanh hơn một INNER JOINvà đó là khi:

  • Một số bảng rất nhỏ (giả sử, dưới 10 hàng);
  • Các bảng không có đủ chỉ mục để bao gồm truy vấn.

Xem xét ví dụ này:

CREATE TABLE #Test1
(
    ID int NOT NULL PRIMARY KEY,
    Name varchar(50) NOT NULL
)
INSERT #Test1 (ID, Name) VALUES (1, 'One')
INSERT #Test1 (ID, Name) VALUES (2, 'Two')
INSERT #Test1 (ID, Name) VALUES (3, 'Three')
INSERT #Test1 (ID, Name) VALUES (4, 'Four')
INSERT #Test1 (ID, Name) VALUES (5, 'Five')

CREATE TABLE #Test2
(
    ID int NOT NULL PRIMARY KEY,
    Name varchar(50) NOT NULL
)
INSERT #Test2 (ID, Name) VALUES (1, 'One')
INSERT #Test2 (ID, Name) VALUES (2, 'Two')
INSERT #Test2 (ID, Name) VALUES (3, 'Three')
INSERT #Test2 (ID, Name) VALUES (4, 'Four')
INSERT #Test2 (ID, Name) VALUES (5, 'Five')

SELECT *
FROM #Test1 t1
INNER JOIN #Test2 t2
ON t2.Name = t1.Name

SELECT *
FROM #Test1 t1
LEFT JOIN #Test2 t2
ON t2.Name = t1.Name

DROP TABLE #Test1
DROP TABLE #Test2

Nếu bạn chạy nó và xem kế hoạch thực hiện, bạn sẽ thấy rằng INNER JOINtruy vấn thực sự có giá cao hơn so với LEFT JOIN, bởi vì nó đáp ứng hai tiêu chí trên. Đó là bởi vì SQL Server muốn thực hiện khớp băm cho INNER JOIN, nhưng các vòng lặp lồng nhau cho LEFT JOIN; cái trước thường nhanh hơn nhiều, nhưng vì số lượng hàng rất ít không có chỉ mục nào để sử dụng, nên thao tác băm hóa ra là phần đắt nhất của truy vấn.

Bạn có thể thấy hiệu ứng tương tự bằng cách viết một chương trình bằng ngôn ngữ lập trình yêu thích của bạn để thực hiện một số lượng lớn tra cứu trong danh sách có 5 phần tử, so với bảng băm có 5 phần tử. Do kích thước, phiên bản bảng băm thực sự chậm hơn. Nhưng tăng nó lên 50 phần tử, hoặc 5000 phần tử và phiên bản danh sách chậm lại khi thu thập thông tin, bởi vì đó là O (N) so với O (1) cho hashtable.

Nhưng thay đổi truy vấn này thành IDcột thay vì Namevà bạn sẽ thấy một câu chuyện rất khác. Trong trường hợp đó, nó thực hiện các vòng lặp lồng nhau cho cả hai truy vấn, nhưng INNER JOINphiên bản có thể thay thế một trong các quét chỉ mục được nhóm bằng một tìm kiếm - có nghĩa là đây sẽ thực sự là một thứ tự cường độ nhanh hơn với số lượng lớn các hàng.

Vì vậy, kết luận ít nhiều là những gì tôi đã đề cập đến một số đoạn trên; đây gần như chắc chắn là một vấn đề về lập chỉ mục hoặc bao phủ chỉ mục, có thể kết hợp với một hoặc nhiều bảng rất nhỏ. Đó là những trường hợp duy nhất theo đó SQL Server đôi khi có thể chọn một kế hoạch thực thi tồi tệ hơn cho INNER JOINa LEFT JOIN.


4
Có một kịch bản khác có thể dẫn đến một NGOÀI RA hoạt động tốt hơn so với THAM GIA VÀO. Xem câu trả lời của tôi dưới đây.
dbenham

12
Tôi muốn chỉ ra rằng về cơ bản không có tài liệu cơ sở dữ liệu để hỗ trợ ý tưởng rằng các phép nối bên trong và các phép nối ngoài khác nhau thực hiện khác nhau. Các kết nối bên ngoài đắt hơn một chút so với các kết nối bên trong, vì khối lượng dữ liệu và kích thước của tập kết quả. Tuy nhiên, các thuật toán cơ bản ( msdn.microsoft.com/en-us/l Library / ms191426 ( v = sql.105 ) .aspx ) giống nhau cho cả hai loại liên kết. Hiệu suất phải tương tự khi chúng trả về lượng dữ liệu tương tự.
Gordon Linoff

3
@Aaronaught. . . Câu trả lời này đã được tham chiếu trong một bình luận cho biết điều gì đó ảnh hưởng đến việc "các kết nối bên ngoài hoạt động kém hơn đáng kể so với các kết nối bên trong". Tôi nhận xét chỉ để chắc chắn rằng việc giải thích sai này không lan truyền.
Gordon Linoff

16
Tôi nghĩ rằng câu trả lời này là sai lệch ở một khía cạnh quan trọng: Bởi vì nó nói rằng "MỘT THAM GIA TRÁI PHIẾU hoàn toàn không nhanh hơn THAM GIA VÀO". Dòng này không đúng. Về mặt lý thuyết, nó không nhanh hơn THAM GIA VÀO. Nó KHÔNG "hoàn toàn không nhanh hơn." Câu hỏi đặc biệt là một câu hỏi hiệu suất. Trong thực tế, bây giờ tôi đã thấy một vài hệ thống (bởi các công ty rất lớn!) Trong đó INNER THAM GIA chậm chạp một cách lố bịch so với OUTER THAM GIA. Lý thuyết và thực hành là những thứ rất khác nhau.
David Frenkel

5
@DavidFrenkel: Điều đó rất khó xảy ra. Tôi yêu cầu được xem so sánh A / B, với các kế hoạch thực hiện, nếu bạn tin rằng sự khác biệt đó là có thể. Có thể nó liên quan đến các kế hoạch thực hiện / truy vấn được lưu trữ hoặc thống kê xấu.
Aaronaught

127

Có một kịch bản quan trọng có thể dẫn đến một phép nối bên ngoài nhanh hơn một phép nối bên trong chưa được thảo luận.

Khi sử dụng phép nối ngoài, trình tối ưu hóa luôn tự do thả bảng nối ngoài khỏi kế hoạch thực hiện nếu các cột nối là PK của bảng ngoài và không có cột nào trong bảng ngoài được tham chiếu bên ngoài phép nối ngoài. Ví dụ SELECT A.* FROM A LEFT OUTER JOIN B ON A.KEY=B.KEYvà B.KEY là PK cho B. Cả Oracle (tôi tin rằng tôi đang sử dụng phiên bản 10) và Sql Server (tôi đã sử dụng 2008 R2) cắt bảng B từ kế hoạch thực hiện.

Điều tương tự không nhất thiết đúng với một phép nối bên trong: SELECT A.* FROM A INNER JOIN B ON A.KEY=B.KEYcó thể hoặc không yêu cầu B trong kế hoạch thực hiện tùy thuộc vào những ràng buộc nào tồn tại.

Nếu A.KEY là khóa ngoại tham chiếu B.KEY, thì trình tối ưu hóa không thể loại bỏ B khỏi kế hoạch vì nó phải xác nhận rằng hàng B tồn tại cho mỗi hàng A.

Nếu A.KEY là khóa ngoại tham chiếu bắt buộc B.KEY, thì trình tối ưu hóa có thể thả B ra khỏi kế hoạch vì các ràng buộc đảm bảo sự tồn tại của hàng. Nhưng chỉ vì trình tối ưu hóa có thể loại bỏ bảng khỏi kế hoạch, không có nghĩa là nó sẽ như vậy. SQL Server 2008 R2 KHÔNG bỏ B khỏi kế hoạch. Oracle 10 DOES thả B khỏi kế hoạch. Thật dễ dàng để thấy cách nối bên ngoài sẽ thực hiện kết nối bên trong trên SQL Server trong trường hợp này.

Đây là một ví dụ tầm thường và không thực tế cho truy vấn độc lập. Tại sao tham gia vào một bảng nếu bạn không cần?

Nhưng điều này có thể là một xem xét thiết kế rất quan trọng khi thiết kế quan điểm. Thường thì chế độ xem "làm mọi thứ" được xây dựng để tham gia mọi thứ mà người dùng có thể cần liên quan đến bảng trung tâm. (Đặc biệt nếu có những người dùng ngây thơ thực hiện các truy vấn đặc biệt không hiểu mô hình quan hệ) Khung nhìn có thể bao gồm tất cả các cột có liên quan từ nhiều bảng. Nhưng người dùng cuối chỉ có thể truy cập các cột từ một tập hợp con của các bảng trong dạng xem. Nếu các bảng được nối với các phép nối ngoài, thì trình tối ưu hóa có thể (và không) loại bỏ các bảng không cần thiết khỏi kế hoạch.

Điều quan trọng là đảm bảo rằng chế độ xem sử dụng các phép nối ngoài cho kết quả chính xác. Như Aaronaught đã nói - bạn không thể thay thế một cách mù quáng OUTER THAM GIA cho INNER THAM GIA và mong đợi kết quả tương tự. Nhưng có những lúc nó có thể hữu ích vì lý do hiệu suất khi sử dụng lượt xem.

Một lưu ý cuối cùng - Tôi chưa kiểm tra tác động đến hiệu suất theo ánh sáng ở trên, nhưng về lý thuyết, có vẻ như bạn có thể thay thế một cách an toàn INNER THAM GIA bằng OUTER THAM GIA nếu bạn cũng thêm điều kiện <FOREIGN_KEY> KHÔNG PHẢI đến mệnh đề where.


5
Tôi thực sự gặp phải vấn đề này khi xây dựng các truy vấn cực kỳ năng động. Tôi đã để lại một INNER THAM GIA mà tôi đang sử dụng và không lấy dữ liệu từ đó và khi tôi chuyển nó sang LEFT THAM GIA (vì tò mò), truy vấn thực sự chạy nhanh hơn.
Erik Philips

1
EDIT - Làm rõ các điều kiện phải tồn tại để trình tối ưu hóa bỏ bảng đã tham gia bên ngoài khỏi kế hoạch thực hiện.
dbenham

2
Một điều rõ ràng nhỏ cho câu trả lời của bạn: Khi cột khóa ngoài là không thể rỗng, INNER THAM GIA và LEFT THAM GIA trở nên tương đương về mặt ngữ nghĩa (nghĩa là mệnh đề WHERE được đề xuất của bạn là không cần thiết); sự khác biệt duy nhất sẽ là kế hoạch thực hiện.
Douglas

2
Mặc dù điều này cho thấy một ví dụ có vẻ tầm thường thực sự, đây là một câu trả lời cực kỳ sâu sắc!
pbalaga

6
+1: Tôi dường như đã gặp phải điều này trên một vài truy vấn khi tôi đang sử dụng các phép nối bên trong với một số bảng rất lớn. Sự kết hợp bên trong đã gây ra sự cố tràn vào tempdb trong kế hoạch truy vấn (tôi giả sử vì lý do đã nêu ở trên - và máy chủ của tôi thiếu RAM để giữ mọi thứ trong bộ nhớ). Chuyển sang các liên kết bên trái đã loại bỏ sự cố tràn sang tempdb, kết quả là một số truy vấn 20-30 giây của tôi hiện chạy theo phân số của một giây. Đây là một vấn đề rất quan trọng khi hầu hết mọi người dường như đưa ra giả thuyết rằng việc tham gia bên trong nhanh hơn.
phosplait

23

Nếu mọi thứ hoạt động như không nên, NHƯNG tất cả chúng ta đều biết mọi thứ không hoạt động theo cách đặc biệt khi nói đến trình tối ưu hóa truy vấn, bộ nhớ đệm và thống kê truy vấn.

Đầu tiên tôi sẽ đề xuất xây dựng lại chỉ mục và số liệu thống kê, sau đó xóa bộ đệm của kế hoạch truy vấn chỉ để đảm bảo rằng điều đó không làm hỏng mọi thứ. Tuy nhiên tôi đã gặp vấn đề ngay cả khi điều đó được thực hiện.

Tôi đã trải qua một số trường hợp tham gia bên trái nhanh hơn tham gia bên trong.

Lý do cơ bản là đây: Nếu bạn có hai bảng và bạn tham gia vào một cột có chỉ mục (trên cả hai bảng). Phép nối bên trong sẽ tạo ra kết quả tương tự cho dù bạn lặp qua các mục trong chỉ mục trên bảng một và khớp với chỉ mục trên bảng hai như thể bạn sẽ làm ngược lại: Lặp lại các mục trong chỉ mục trên bảng hai và khớp với chỉ mục trong bảng một. Vấn đề là khi bạn có số liệu thống kê sai lệch, trình tối ưu hóa truy vấn sẽ sử dụng số liệu thống kê của chỉ mục để tìm bảng có ít mục khớp nhất (dựa trên các tiêu chí khác của bạn). Nếu bạn có hai bảng với mỗi bảng 1 triệu, trong bảng một, bạn có 10 hàng khớp và trong bảng hai bạn có 100000 hàng khớp. Cách tốt nhất là quét chỉ mục trên bảng một và khớp 10 lần trong bảng hai. Ngược lại sẽ là quét chỉ mục vòng lặp trên 100000 hàng và cố gắng khớp 100000 lần và chỉ có 10 thành công. Vì vậy, nếu số liệu thống kê không chính xác, trình tối ưu hóa có thể chọn bảng và chỉ mục sai để lặp lại.

Nếu trình tối ưu hóa chọn tối ưu hóa phép nối trái theo thứ tự được viết, nó sẽ hoạt động tốt hơn so với phép nối bên trong.

NHƯNG, trình tối ưu hóa cũng có thể tối ưu hóa một tham gia phụ bên trái tối ưu như một liên kết bán bên trái. Để làm cho nó chọn một trong những bạn muốn bạn có thể sử dụng gợi ý thứ tự lực lượng.


18

Hãy thử cả hai truy vấn (một truy vấn có tham gia bên trong và bên trái) OPTION (FORCE ORDER)ở cuối và đăng kết quả. OPTION (FORCE ORDER)là một gợi ý truy vấn buộc trình tối ưu hóa xây dựng kế hoạch thực hiện với thứ tự tham gia mà bạn đã cung cấp trong truy vấn.

Nếu INNER JOINbắt đầu thực hiện nhanh như LEFT JOIN, đó là vì:

  • Trong một truy vấn được tạo hoàn toàn bởi INNER JOINs, thứ tự tham gia không thành vấn đề. Điều này mang lại sự tự do cho trình tối ưu hóa truy vấn để ra lệnh cho các phép nối khi thấy phù hợp, vì vậy vấn đề có thể phụ thuộc vào trình tối ưu hóa.
  • Với LEFT JOIN, đó không phải là trường hợp vì việc thay đổi thứ tự tham gia sẽ thay đổi kết quả của truy vấn. Điều này có nghĩa là công cụ phải tuân theo thứ tự tham gia mà bạn đã cung cấp trên truy vấn, có thể tốt hơn so với công cụ được tối ưu hóa.

Không biết điều này có trả lời câu hỏi của bạn không nhưng tôi đã từng tham gia một dự án có các truy vấn rất phức tạp khi thực hiện các phép tính, điều này hoàn toàn làm hỏng trình tối ưu hóa. Chúng tôi đã có trường hợp a FORCE ORDERsẽ giảm thời gian thực hiện truy vấn từ 5 phút xuống còn 10 giây.


9

Đã thực hiện một số so sánh giữa các kết hợp bên ngoài và bên trong bên trái và không thể tìm thấy một sự khác biệt nhất quán. Có nhiều biến số. Đang làm việc trên cơ sở dữ liệu báo cáo với hàng ngàn bảng với nhiều trường có số lượng lớn, nhiều thay đổi theo thời gian (phiên bản của nhà cung cấp và quy trình làm việc cục bộ). Không thể tạo tất cả các kết hợp của các chỉ mục bao trùm để đáp ứng nhu cầu của một loạt các truy vấn như vậy và xử lý dữ liệu lịch sử. Đã thấy các truy vấn bên trong giết chết hiệu năng của máy chủ vì hai bảng lớn (hàng triệu đến hàng chục triệu hàng) được nối bên trong cả hai kéo theo một số lượng lớn các trường và không tồn tại chỉ mục che phủ.

Tuy nhiên, vấn đề lớn nhất dường như không xuất hiện trong các cuộc thảo luận ở trên. Có thể cơ sở dữ liệu của bạn được thiết kế tốt với các kích hoạt và xử lý giao dịch được thiết kế tốt để đảm bảo dữ liệu tốt. Của tôi thường có giá trị NULL nơi họ không mong đợi. Có, các định nghĩa bảng có thể thực thi no-Nulls nhưng đó không phải là một tùy chọn trong môi trường của tôi.

Vì vậy, câu hỏi là ... bạn có thiết kế truy vấn của mình chỉ cho tốc độ không, ưu tiên cao hơn cho xử lý giao dịch chạy cùng mã hàng nghìn lần một phút. Hoặc bạn đi cho chính xác mà một tham gia bên ngoài bên trái sẽ cung cấp. Hãy nhớ rằng các phép nối bên trong phải tìm thấy kết quả khớp ở cả hai bên, do đó, một NULL không mong muốn sẽ không chỉ xóa dữ liệu khỏi hai bảng mà có thể là toàn bộ hàng thông tin. Và nó xảy ra rất độc đáo, không có thông báo lỗi.

Bạn có thể rất nhanh vì nhận được 90% dữ liệu cần thiết và không phát hiện ra các liên kết bên trong đã âm thầm xóa thông tin. Đôi khi các kết nối bên trong có thể nhanh hơn, nhưng tôi không tin bất cứ ai đưa ra giả định đó trừ khi họ đã xem xét kế hoạch thực hiện. Tốc độ là quan trọng, nhưng độ chính xác là quan trọng hơn.


8

Các vấn đề về hiệu suất của bạn có nhiều khả năng là do số lượng tham gia bạn đang thực hiện và liệu các cột bạn đang tham gia có chỉ mục hay không.

Trường hợp xấu nhất bạn có thể dễ dàng thực hiện 9 lần quét toàn bộ bảng cho mỗi lần tham gia.


7

Tham gia bên ngoài có thể cung cấp hiệu suất cao khi được sử dụng trong quan điểm.

Giả sử bạn có một truy vấn liên quan đến một khung nhìn và khung nhìn đó bao gồm 10 bảng được nối với nhau. Giả sử truy vấn của bạn chỉ xảy ra để sử dụng các cột từ 3 trong số 10 bảng đó.

Nếu 10 bảng đó đã được nối bên trong với nhau, thì trình tối ưu hóa truy vấn sẽ phải tham gia tất cả chúng mặc dù bản thân truy vấn của bạn không cần 7 trên 10 bảng. Đó là bởi vì chính bên trong tham gia có thể lọc dữ liệu, làm cho chúng cần thiết để tính toán.

Thay vào đó, nếu 10 bảng đó được liên kết ngoài cùng với nhau, thì trình tối ưu hóa truy vấn sẽ chỉ thực sự kết hợp với những bảng cần thiết: 3 trong số 10 bảng trong trường hợp này. Đó là vì bản thân các phép nối không còn lọc dữ liệu và do đó các phép nối không được sử dụng có thể bị bỏ qua.

Nguồn: http://www.sqlservercentral.com/bloss/sql_coach/2010/07/29/poor-little-misunderpered-view/


1
Tuyên bố của bạn về "tham gia ngoài" là sai lệch và có khả năng không chính xác. Bên ngoài có nghĩa là dữ liệu ở phía bên kia không cần tồn tại - và nếu nó không thay thế NULL. Trong các trường hợp cụ thể, RDBMS có thể "bỏ qua" chúng (xem câu trả lời ở trên từ dbenham). TUY NHIÊN - bên ngoài so với bên trong có thể khiến truy vấn của bạn trả về kết quả hoàn toàn khác nhau. INNER có nghĩa là - đưa ra kết quả mà một mục nằm trong CẢ HAI A & B. LEFT OUTER có nghĩa là tất cả A và tùy chọn B nếu nó tồn tại. Trường hợp đầu tiên - bạn nhận được một số hàng, trong giây thứ hai bạn nhận được TẤT CẢ các hàng.
ripvlan

1
@ripvlan Tất nhiên, các kết nối bên ngoài và bên trong không phải lúc nào cũng có thể thay thế cho nhau. Câu hỏi ban đầu là về hiệu suất, ngụ ý rằng chúng ta đang nói về các trường hợp tham gia sẽ trả về cùng một kết quả.
MarredCheese

1
Có và - OUTER có thể gây ra sự cố về hiệu suất vì nó sẽ khiến tất cả các hàng (nhiều dữ liệu) được trả về. Giả định của bạn rằng các truy vấn dẫn đến cùng một đầu ra là hợp lý - tuy nhiên điều đó không đúng trong trường hợp chung và cụ thể cho từng thiết kế db. Và đối với những người không quen thuộc 100% với đại số quan hệ có thể khiến họ đau buồn. Quan điểm của tôi là chỉ cung cấp cái nhìn sâu sắc hơn cho những người đọc tìm kiếm lời khuyên này và rằng TRÁI / PHẢI sẽ không giải quyết một cách kỳ diệu một vấn đề và có thể gây ra nhiều vấn đề hơn. Đó là sức mạnh còn lại cho cấp 300 :-)
ripvlan

2

Tôi đã tìm thấy một cái gì đó thú vị trong máy chủ SQL khi kiểm tra xem các phép nối bên trong có nhanh hơn các phép nối trái không.

Nếu bạn không bao gồm các mục của bảng được nối bên trái, trong câu lệnh select, phép nối trái sẽ nhanh hơn truy vấn tương tự với phép nối bên trong.

Nếu bạn bao gồm bảng đã nối bên trái trong câu lệnh select, thì phép nối bên trong có cùng truy vấn sẽ bằng hoặc nhanh hơn phép nối trái.


0

Từ những so sánh của tôi, tôi thấy rằng họ có cùng một kế hoạch thực hiện. Có ba kịch bản:

  1. Nếu và khi họ trả về cùng một kết quả, họ có cùng tốc độ. Tuy nhiên, chúng ta phải nhớ rằng chúng không phải là cùng một truy vấn và LEFT THAM GIA sẽ có thể trả về nhiều kết quả hơn (khi một số điều kiện ON không được đáp ứng) --- đây là lý do tại sao nó thường chậm hơn.

  2. Khi bảng chính (đầu tiên không phải là một trong kế hoạch thực hiện) có điều kiện hạn chế (WHERE id =?) Và điều kiện BẬT tương ứng nằm trên một giá trị NULL, bảng "phải" không được nối --- đây là khi THAM GIA nhanh hơn.

  3. Như đã thảo luận ở Điểm 1, thông thường INNER THAM GIA hạn chế hơn và trả về ít kết quả hơn và do đó nhanh hơn.

Cả hai sử dụng (giống nhau) chỉ số.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.