Việc thêm DISTINCT
vào ví dụ sau có ảnh hưởng gì đến thời gian chạy truy vấn không?
Có phải là khôn ngoan để sử dụng nó như một gợi ý đôi khi?
SELECT *
FROM A
WHERE A.SomeColumn IN (SELECT DISTINCT B.SomeColumn FROM B)
Việc thêm DISTINCT
vào ví dụ sau có ảnh hưởng gì đến thời gian chạy truy vấn không?
Có phải là khôn ngoan để sử dụng nó như một gợi ý đôi khi?
SELECT *
FROM A
WHERE A.SomeColumn IN (SELECT DISTINCT B.SomeColumn FROM B)
Câu trả lời:
Khi tự hỏi về những điều như thế này, bạn nên so sánh các kế hoạch thực hiện cho các truy vấn của bạn.
Tất nhiên, hình dạng của kế hoạch thực hiện cho truy vấn của bạn sẽ khác nhau tùy thuộc vào số lượng hàng bạn có trong các bảng và chỉ mục nào được xác định.
Một kịch bản cho thấy không có sự khác biệt về hiệu suất là khi có nhiều hàng đáng kể hơn A
so với có B
. Trình tối ưu hóa sau đó sẽ chọn B
làm bảng điều khiển trong một vòng lặp lồng nhau A
. Để có được kết quả chính xác, nó phải sử dụng Tập hợp luồng trên bảng B
trong cả hai truy vấn để chỉ nhận các hàng riêng biệt từ đó B
. Vì vậy, trong trường hợp này, từ khóa riêng biệt không có tác động đến hiệu suất.
Kế hoạch thực hiện cho hai trường hợp rõ ràng khác để kiểm tra, nhiều hàng trong B hơn A và số lượng hàng bằng nhau trong các bảng, cũng hiển thị chính xác kế hoạch thực hiện cho các truy vấn.
Cập nhật
Trước khi tối ưu hóa truy vấn diễn ra, truy vấn sẽ trải qua giai đoạn đơn giản hóa. Bạn có thể thấy cây logic trông như thế nào khi sử dụng cờ theo dõi 8606.
Cây đầu vào cho các truy vấn rõ ràng khác nhau nhưng sau khi đơn giản hóa chúng giống nhau.
Tham khảo: Thêm Trình tối ưu hóa truy vấn không có giấy tờ và Cờ tối ưu hóa truy vấn Lặn sâu - Phần 2
Cây đầu vào và cây đơn giản hóa cho truy vấn bằng cách sử dụng riêng biệt:
*** Input Tree: ***
LogOp_Project QCOL: [xx].[dbo].[A].SomeColumn
LogOp_Select
LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
ScaOp_SomeComp 2
ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
LogOp_GbAgg OUT(QCOL: [xx].[dbo].[B].SomeColumn,) BY(QCOL: [xx].[dbo].[B].SomeColumn,)
LogOp_Project
LogOp_Project
LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
AncOp_PrjList
AncOp_PrjList
AncOp_PrjList
AncOp_PrjList
*******************
*** Simplified Tree: ***
LogOp_LeftSemiJoin
LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
ScaOp_Comp x_cmpEq
ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
ScaOp_Identifier QCOL: [xx].[dbo].[B].SomeColumn
*******************
Cây đầu vào và cây đơn giản hóa cho truy vấn không sử dụng riêng biệt:
*** Input Tree: ***
LogOp_Project QCOL: [xx].[dbo].[A].SomeColumn
LogOp_Select
LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
ScaOp_SomeComp 2
ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
LogOp_Project
LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
AncOp_PrjList
AncOp_PrjList
*******************
*** Simplified Tree: ***
LogOp_LeftSemiJoin
LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
ScaOp_Comp x_cmpEq
ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
ScaOp_Identifier QCOL: [xx].[dbo].[B].SomeColumn
*******************