Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Đặt và xác định mục tiêu hàng trong kế hoạch thực thi

Giới thiệu

Tài liệu sản phẩm SQL Server hơi nhẹ về chủ đề mục tiêu hàng . Các tài liệu tham khảo chính thức có trong:

  • Gợi ý (Giao dịch-SQL) - Truy vấn (FASTDISABLE_OPTIMIZER_ROWGOAL gợi ý)
  • DBCC TRACEON - Cờ theo dõi (Giao dịch-SQL) (cờ theo dõi 4138)
  • Có thể mất nhiều thời gian để chạy một truy vấn nếu trình tối ưu hoá truy vấn sử dụng toán tử Top (KB 2667211)

Khi mọi người yêu cầu nhiều thông tin hơn những gì được cung cấp ở đó, tôi thường giới thiệu cho họ một hoặc nhiều thông tin sau:

  • Các Mục tiêu Hàng đang Thực hiện bởi Nhóm Tối ưu hoá Truy vấn Máy chủ SQL
  • Các Mục tiêu Hàng được xem lại - Hướng dẫn gợi ý NHANH cũng bởi Nhóm Tối ưu hoá Truy vấn Máy chủ SQL
  • Row Goals Gone Rogue của Bart Duncan
  • Bên trong Trình tối ưu hoá:Độ sâu của Mục tiêu Hàng do tôi thực hiện
  • Mẹo điều chỉnh SSIS mà mọi người đều bỏ qua của Rob Farley

Tóm lại ngắn gọn:Tính năng mục tiêu hàng cho phép trình tối ưu hóa tạo kế hoạch thực thi (hoặc (các) phần của kế hoạch thực thi) với mục đích trả về một số hàng nhất định một cách nhanh chóng. Điều này trái ngược với hành vi bình thường (không có mục tiêu hàng) nhằm mục đích tìm ra một kế hoạch được tối ưu hóa cho toàn bộ tập hợp kết quả tiềm năng.

Chiến lược mục tiêu hàng nói chung có nghĩa là ưu tiên các hoạt động điều hướng không chặn (ví dụ:kết hợp các vòng lặp lồng nhau, tìm kiếm chỉ mục và tra cứu) hơn các hoạt động chặn, dựa trên tập hợp như sắp xếp và băm. Điều này có thể hữu ích bất cứ khi nào khách hàng có thể hưởng lợi từ việc khởi động nhanh chóng và dòng ổn định của các hàng (có lẽ với thời gian thực hiện tổng thể lâu hơn - xem bài đăng của Rob Farley ở trên). Ngoài ra còn có các cách sử dụng truyền thống và rõ ràng hơn, ví dụ:trong việc trình bày kết quả một trang tại một thời điểm.

Đương nhiên, có một yếu tố rủi ro liên quan đến kế hoạch mục tiêu hàng. Nếu mọi thứ diễn ra rộng rãi như mong đợi của trình tối ưu hóa (với thông tin có sẵn và các giả định lập mô hình), kế hoạch thực thi sẽ bắt đầu phát trực tuyến số hàng được yêu cầu nhanh hơn và hiệu quả hơn so với trường hợp không có mục tiêu hàng.

Thật không may, khi chiến lược mục tiêu theo hàng sai, nó có thể là một thảm họa về hiệu suất (xem bài đăng của Bart Duncan). Điều này có thể xảy ra, ví dụ:khi trình tối ưu hóa có thông tin không đầy đủ, gặp phải phân phối dữ liệu không thuận lợi hoặc đưa ra giả định không an toàn. Trong mọi trường hợp, nguyên nhân của hiệu suất kém hầu như luôn luôn là do nhiều hàng cần được xử lý tại thời điểm thực thi hơn so với dự kiến ​​của trình tối ưu hóa.

Nó có thể rất hữu ích khi xác định các khu vực kế hoạch thực thi bị ảnh hưởng bởi mục tiêu hàng, vì nó giúp chúng tôi hiểu tại sao trình tối ưu hóa đã thực hiện các lựa chọn mà nó đã làm. Điều này đặc biệt quan trọng khi logic mục tiêu hàng tạo ra kết quả bất lợi. Nếu không hiểu vai trò của mục tiêu hàng, có thể trông như thể trình tối ưu hóa chỉ đơn giản là đánh giá thấp số lượng hàng, khiến mọi người nhìn nhầm chỗ (ví dụ:thống kê) cho một nguyên nhân gốc rễ.

Đặt mục tiêu hàng

Sẽ dễ dàng hơn rất nhiều để tìm kiếm các hiệu ứng mục tiêu hàng nếu người ta biết những thứ nào có thể khiến mục tiêu hàng được đặt ngay từ đầu. Tài liệu chính thức thường nói về các mục tiêu hàng được kết hợp với các từ khóa TOP , FAST , INEXISTS . Điều này có thể để lại cho người đọc một sự hiểu biết không đầy đủ hoặc sai lệch, vì vậy cần dành một chút thời gian để làm rõ một số khía cạnh.

Tôi muốn nhấn mạnh ngay trước rằng sử dụng các từ khóa T-SQL cụ thể trong một truy vấn không đảm bảo rằng mục tiêu hàng sẽ được đặt . Tài liệu chính thức đề cập đến các từ khóa nhất định để giúp mọi người xác định các tình huống phổ biến trong đó mục tiêu hàng có thể được giới thiệu mà không vướng vào quá nhiều kỹ thuật.

Điểm chung thứ hai cần lưu ý là mục tiêu hàng chỉ được đặt khi mục tiêu nhỏ hơn ước tính thông thường . Rốt cuộc, không có nhiều điểm để tạo ra một phân đoạn kế hoạch được tối ưu hóa cho 100 hàng nếu toàn bộ điều này chỉ được mong đợi để tạo ra 50 hàng. Để rõ ràng hơn, điểm này luôn áp dụng cho tất cả các cách có thể đặt mục tiêu hàng. Nếu bạn đang mong đợi một mục tiêu hàng, nhưng không thấy một mục tiêu, đây có thể là một nguyên nhân.

Cuối cùng, đối với phần mở đầu, hãy lưu ý rằng mục tiêu hàng là thứ tối ưu hóa dựa trên chi phí; mục tiêu hàng ảnh hưởng đến các lựa chọn của trình tối ưu hóa, vì vậy nếu không có lựa chọn nào được thực hiện (tức là một kế hoạch tầm thường) thì sẽ không có hiệu ứng mục tiêu hàng.

Bây giờ chúng ta hãy xem xét những thứ có thể đặt mục tiêu hàng:

NHANH CHÓNG và HÀNG ĐẦU

Sử dụng FAST gợi ý truy vấn là một cách đáng tin cậy để đặt mục tiêu hàng ở gốc của kế hoạch thực hiện (tùy thuộc vào các ngoại lệ chung đã nêu ở trên). A SET ROWCOUNT n câu lệnh cũng đặt mục tiêu hàng cấp cao nhất tương tự (khi n tất nhiên không phải là 0) đối với các câu lệnh mà nó áp dụng.

Viết TOP mệnh đề trong một truy vấn cũng rất thường dẫn đến một mục tiêu hàng. Miễn là kế hoạch thực thi đã hoàn thành có tính năng toán tử Hàng đầu vật lý, có khả năng ít nhất một phần của kế hoạch bên dưới toán tử Hàng đầu đã bị ảnh hưởng bởi mục tiêu hàng (một lần nữa, các điều khoản và điều kiện chung được áp dụng).

Lưu ý rằng các toán tử hàng đầu được giới thiệu bởi trình tối ưu hóa truy vấn (không có TOP do truy vấn chỉ định mệnh đề) cũng có thể đặt mục tiêu hàng. Điều này rất quan trọng, vì có rất nhiều cách để điều này có thể xảy ra, chẳng hạn như khi lọc trên một số hàng đơn giản, như được hiển thị trong truy vấn AdventureWorks sau:

SELECT
    THN.RowNum,
    THN.TransactionID 
FROM 
(
    SELECT 
        TH.TransactionID, 
        RowNum = 
            ROW_NUMBER() OVER (
                ORDER BY TH.TransactionID ASC)
    FROM Production.TransactionHistory AS TH
    WHERE
        TH.ProductID = 400
) AS THN
WHERE
    THN.RowNum >= 10
    AND THN.RowNum < 20
ORDER BY
    THN.RowNum ASC;

Kế hoạch thực thi cho truy vấn đó bao gồm toán tử Hàng đầu được trình tối ưu hóa thêm vào (để giới hạn số hàng được xử lý là 20):

Các mục tiêu hàng liên quan đến hàng đầu không cần xuất hiện ở gốc của kế hoạch thực thi. Đây là một lý do tại sao một số phần của kế hoạch có thể có mục tiêu hàng, trong khi các phần khác thì không.

TRONG và TỒN TẠI

Tài liệu đề cập đến INEXISTS bởi vì đây là hai cách phổ biến để thể hiện bán tham gia hoặc chống tham gia trong T-SQL. Sử dụng một trong hai từ khóa theo cách không tạo ra liên kết bán hoặc chống sẽ không đặt mục tiêu hàng.

T-SQL không cung cấp cho chúng ta cách viết một kết nối semi hoặc anti trực tiếp (mặc dù điều thú vị là U-SQL có), vì vậy chúng ta phải sử dụng cú pháp gián tiếp như thế này để thay thế (Aaron Bertrand đã xem xét các tùy chọn T-SQL chính trong phần trước bài báo).

Ví dụ:

-- Using IN
SELECT P.ProductID
FROM Production.Product AS P
WHERE P.ProductID IN
(
    SELECT TH.ProductID
    FROM Production.TransactionHistory AS TH
);
 
-- Using EXISTS
SELECT P.ProductID
FROM Production.Product AS P
WHERE EXISTS
(
    SELECT * 
    FROM Production.TransactionHistory AS TH
    WHERE
        TH.ProductID = P.ProductID
);
 
-- Using INTERSECT (also removes duplicates but P.ProductID is a key)
SELECT P.ProductID
FROM Production.Product AS P
INTERSECT
SELECT TH.ProductID
FROM Production.TransactionHistory AS TH;

Cả ba biểu mẫu đều tạo ra cùng một kế hoạch thực thi, có một kết nối bán phần:

Một lần nữa, liên kết bán / chống lại quan trọng từ quan điểm mục tiêu hàng, không phải từ khóa T-SQL. Truy vấn sau đây cũng tạo ra một bán kết hợp giống hệt nhau kế hoạch thực thi chỉ sử dụng DISTINCTINNER JOIN thông thường :

SELECT DISTINCT
    P.ProductID
FROM Production.Product AS P
INNER JOIN Production.TransactionHistory AS TH
    ON TH.ProductID = P.ProductID;

Có thể dễ dàng xây dựng các ví dụ tương tự để chống nối (mặc dù cần cẩn thận khi sử dụng NOT IN ).

Ví dụ thứ hai (ít phổ biến hơn nhiều), INEXISTS từ khóa cũng có thể được sử dụng với IF để tạo một kết nối bán:

IF EXISTS (SELECT * FROM Production.TransactionHistory WHERE ProductID = 331)
    PRINT 'Row found';
 
IF 331 IN (SELECT ProductID FROM Production.TransactionHistory)
    PRINT 'Row found';
 
IF 331 = ANY (SELECT ProductID FROM Production.TransactionHistory)
    PRINT 'Row found';

Tất cả những điều trên tạo ra cùng một kế hoạch thực thi với một kết nối bán vòng lồng nhau:

Cho dù kết hợp bán / chống được thể hiện theo cách nào, nó ít có khả năng hơn TOP hoặc FAST để dẫn đến một mục tiêu hàng. Tôi sẽ dành một bài đăng riêng về cách thức hoạt động chi tiết và lý do tại sao các kiểu liên kết này có thể kích hoạt logic mục tiêu hàng.

Xác định mục tiêu hàng

Theo kinh nghiệm của tôi, mọi người thường bỏ lỡ tác động của các mục tiêu hàng trong kế hoạch thực hiện.

Không có gì lạ, kể từ trước SQL Server 2017 CU3 (bản cập nhật:hiện được chuyển sang 2016 SP2 và 2014 SP3), không có cách nào được ghi lại để xem thông tin về mục tiêu hàng trong kế hoạch thực thi! Bản cập nhật đó bao gồm:

  • Thông tin mục tiêu hàng của trình tối ưu hóa trong kế hoạch thực thi truy vấn được thêm vào SQL Server 2014, 2016 và 2017

Tính năng nâng cao này bổ sung thêm tính năng Ước tínhRowsWithoutRowGoal thuộc tính cho từng toán tử kế hoạch bị ảnh hưởng bởi mục tiêu hàng .

Thuộc tính mới hiển thị ở tất cả những nơi thông thường (ví dụ:DMV, bộ nhớ cache của gói) nhưng chưa có trong các gói đồ họa của SQL Server Management Studio (tối đa và bao gồm SSMS phiên bản 17.4). Máy chủ SQL có gửi thuộc tính mới, nhưng kế hoạch đồ họa SSMS loại bỏ các bit không khớp với phiên bản cục bộ của lược đồ kế hoạch xml.

Phiên bản 17.5 của SSMS dự kiến ​​sẽ xuất xưởng với lược đồ xml cập nhật và các phần tử giao diện người dùng, làm cho thuộc tính mới hiển thị. SentryOne Plan Explorer đã hiển thị thuộc tính mới trong chế độ xem xml thô, vì nó không có bất kỳ lý do gì để loại bỏ thông tin, nhưng sẽ cần cập nhật để kết hợp thông tin mục tiêu hàng mới vào các vị trí khác (chẳng hạn như Sơ đồ kế hoạch ). Tôi hy vọng nó sẽ đi vào chú giải công cụ trước tiên.

Các giới hạn SSMS ở trên áp dụng cho các kế hoạch có được bằng cách yêu cầu một kế hoạch thực thi đồ họa ước tính hoặc thực tế trong giao diện người dùng. Nhìn vào xml bên dưới sơ đồ đồ họa cũng không hiển thị thuộc tính mới.

Tuy nhiên, việc yêu cầu đầu ra chương trình xml thô một cách riêng biệt sẽ không loại bỏ thuộc tính mới. Điều này có thể đạt được với ví dụ:SET SHOWPLAN_XML ON cho một kế hoạch ước tính, hoặc SET STATISTICS XML ON cho một kế hoạch thực tế. Trong cả hai trường hợp, tùy chọn SSMS để hiển thị các kế hoạch thực tế bằng đồ họa phải được tắt để ngăn SSMS chặn xml và loại bỏ nó. Nhấp vào kết quả xml sẽ mở ra ở dạng xem xml, không phải dưới dạng đồ họa, vì xác thực lược đồ chương trình không thành công.

Suy ra sự hiện diện của mục tiêu hàng

Có thể thông tin kế hoạch mục tiêu hàng mới sẽ được thêm vào các phiên bản SQL Server trước đó trong một bản cập nhật trong tương lai, nhưng không có tin tức chính thức về điều đó tại thời điểm viết bài. Trong khi chờ đợi, chúng tôi chỉ còn cách cố gắng suy luận sự hiện diện của một mục tiêu hàng từ thông tin khác có sẵn trong các kế hoạch thực thi. Có nhiều cách để thực hiện việc này, nhưng không có cách nào đặc biệt đầy đủ hoặc thuận tiện.

Ví dụ:một mục tiêu hàng có thể đang hoạt động:

  • Trong đó Chi phí Nhà điều hành Ước tính nhỏ hơn tổng của Chi phí I / O ước tính Chi phí CPU ước tính , nhân với Số lần thực thi ước tính khi cần thiết
  • Trong đó Số lượng hàng ước tính thuộc tính của một chỉ mục hoặc quét bảng (không có vị từ dư) nhỏ hơn Số lượng bảng bất động sản. Ước tính bản số cho một lần quét không hạn chế thông thường có thể được mong đợi để khớp với bản số của đối tượng bên dưới; khi có sự khác biệt, mục tiêu hàng có thể chịu trách nhiệm.
  • Người dùng SQL Server 2016 SP1 trở đi cũng có thể suy ra sự hiện diện của mục tiêu hàng bằng cách so sánh Số lượng hàng ước tính thuộc tính cho toán tử truy cập dữ liệu vào Số lượng hàng ước tính được đọc bất động sản. Điều này cũng chỉ áp dụng cho các toán tử truy cập dữ liệu không có vị từ dư (nhưng bao gồm cả Tìm kiếm chỉ mục một cách hữu ích).

Đôi khi, mọi người cũng giả định rằng một mục tiêu hàng sẽ xuất hiện dưới bất kỳ toán tử Hàng đầu nào trong một kế hoạch. Đây là một cách tiếp cận không đầy đủ và không phải lúc nào cũng chính xác, nhưng nó có ưu điểm là đơn giản (và tốt hơn là không có gì).

Chúng tôi cũng có thể so sánh kế hoạch quan tâm với kế hoạch thu được khi tính năng mục tiêu hàng bị vô hiệu hóa (sử dụng cờ theo dõi 4138 hoặc DISABLE_OPTIMIZER_ROWGOAL tương đối mới gợi ý truy vấn). Đây là một ý tưởng hợp lý, nhưng kế hoạch thứ hai thường khác với kế hoạch đầu tiên đến mức không thể đưa ra so sánh có ý nghĩa nào. Tôi cho là ít nhất nó có thể thúc đẩy điều tra thêm.

Tùy chọn cờ theo dõi không có tài liệu

Khi cần phân tích kế hoạch chi tiết, công cụ truy cập của tôi để xem xét các mục tiêu hàng từ lâu đã là sự kết hợp của các cờ theo dõi không có tài liệu, hiển thị tại cây toán tử đầu ra của trình tối ưu hóa.

Hãy xem một ví dụ (điều đó cũng cho thấy mục tiêu hàng chỉ được đặt như thế nào khi mục tiêu nhỏ hơn ước tính thông thường).

Truy vấn AdventureWorks đồ chơi sau có ước tính là 29 hàng (không có mục tiêu hàng):

SELECT
    TH.TransactionID
FROM Production.TransactionHistory AS TH
WHERE
    TH.Quantity = 100;

Kế hoạch thực hiện là:

Lưu ý rằng bộ lọc trên Quantity đã được đẩy vào quá trình quét như một vị từ còn lại. Phiên bản hiện đại của SQL Server có các thuộc tính Số lượng hàng ước tính =29 Hàng ước tính sẽ đọc =113,443 trên Quét chỉ mục theo cụm để chỉ ra rằng 113.443 hàng sẽ được xử lý để cuối cùng tạo ra 29 hàng vượt qua bộ lọc.

Sửa đổi truy vấn để yêu cầu 28 hàng bằng cách sử dụng TOP đặt mục tiêu hàng:

SELECT TOP (28)
    TH.TransactionID
FROM Production.TransactionHistory AS TH
WHERE
    TH.Quantity = 100
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8607, QUERYTRACEON 8612);

Các cờ theo dõi kết hợp để tạo ra kết quả như sau (trong tab thông báo SSMS):

*** Output Tree: ***
PhyOp_Top NoTies 
[ Card=28 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 0.742065 ]
    PhyOp_Filter 
    [ Card=29 Cost(RowGoal 28,ReW 0,ReB 0,Dist 0,Total 0)= 0.742063 ]
    PhyOp_Range TBL: Production.TransactionHistory(alias TBL: TH)
    [ Card=113443 Cost(RowGoal 109531,ReW 0,ReB 0,Dist 0,Total 0)= 0.689488 ]
    ScaOp_Comp x_cmpEq
        ScaOp_Identifier QCOL: [TH].Quantity
        ScaOp_Const TI(int,ML=4) XVAR(int,Not Owned,Value=100)
    ScaOp_Const TI(bigint,Null,ML=8) XVAR(bigint,Not Owned,Value=28)
    ScaOp_Const TI(bigint,ML=8) XVAR(bigint,Not Owned,Value=0)

Kết quả đó cho thấy:

  • TOP (28) chính nó không có mục tiêu hàng (vì nó được mong đợi tạo ra tất cả 28 hàng có thể có của nó).
  • Bộ lọc (trên Quantity = 100 ) có mục tiêu hàng là 28 được đặt. Nếu không có mục tiêu hàng, ước tính là 29 hàng như trước đây.
  • Quét phạm vi chỉ mục có mục tiêu hàng là 109,531. Đây là số hàng mà trình tối ưu hóa dự kiến ​​sẽ phải chuyển đến Bộ lọc để đáp ứng mục tiêu của Bộ lọc là 28 hàng. Nếu không có mục tiêu hàng, ước tính quét phạm vi chỉ mục là 113.443 hàng (tổng số lượng của bảng).

Việc sử dụng số mục tiêu hàng đã điều chỉnh (và chi phí ước tính có được) là điều làm sai lệch các lựa chọn của trình tối ưu hóa đối với chiến lược điều hướng không chặn. Các tính toán sửa đổi không thay đổi hình dạng kế hoạch trong ví dụ đồ chơi này, đơn giản là vì không có chiến lược nào rẻ hơn để phân phối 28 hàng (thay vì 29). Trong các truy vấn phức tạp hơn (=thực tế), ảnh hưởng của mục tiêu hàng có thể rất đáng kể.

Thông tin kế hoạch mới có sẵn trong SQL Server 2017 CU3 không cung cấp mức độ chi tiết hoàn toàn giống như các cờ theo dõi (đầu ra chương trình CU3 2017 viết tắt cho rõ ràng):

<RelOp NodeId="0" PhysicalOp="Top" EstimateRows="28">
    <RelOp NodeId="1" PhysicalOp="Clustered Index Scan" EstimateRows="28" EstimateRowsWithoutRowGoal="29" EstimatedRowsRead="113443">
    </RelOp>
</RelOp>

Lưu ý thuộc tính mục tiêu hàng mới. Thật không may, việc đẩy bộ lọc vào quá trình quét dưới dạng phần dư đã dẫn đến mất thông tin về mục tiêu hàng quét (109,531). Điều này để lại cho chúng tôi thông tin hơi sai lệch trong Dự toán đọc thuộc tính. Có lẽ bản cập nhật trong tương lai sẽ giải quyết vấn đề này (có thể bằng cách thêm ước tínhRowsReadWithoutRowGoal thuộc tính!) ai biết được.

Trong thời gian chờ đợi, chúng tôi có thể sử dụng một cờ theo dõi không có tài liệu khác (9130) để ngăn việc đẩy bộ lọc vào quá trình quét như một vị từ còn lại, hoàn toàn cho mục đích chẩn đoán kế hoạch. Thông tin kế hoạch sau đó là:

<RelOp NodeId="0" PhysicalOp="Top" EstimateRows="28">
    <RelOp NodeId="1" PhysicalOp="Filter" EstimateRows="28" EstimateRowsWithoutRowGoal="29">
        <RelOp NodeId="2" PhysicalOp="Clustered Index Scan" EstimateRows="109531" EstimateRowsWithoutRowGoal="113443" EstimatedRowsRead="113443">
        </RelOp>
    </RelOp>
</RelOp>

Điều này hiện chứa cùng mức thông tin với tổ hợp cờ theo dõi không có tài liệu. Kế hoạch đồ họa ước tính (với TF 9130) là:

Chạy cùng một truy vấn với TOP (29) cho thấy không có mục tiêu hàng khi mục tiêu bằng hoặc lớn hơn ước tính thông thường:

SELECT TOP (29)
    TH.TransactionID
FROM Production.TransactionHistory AS TH
WHERE
    TH.Quantity = 100
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8607, QUERYTRACEON 8612, QUERYTRACEON 9130);

Đầu ra của tab thông báo là:

*** Output Tree: ***
PhyOp_Top NoTies 
[ Card=29 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 0.768451 ]
    PhyOp_Filter 
    [ Card=29 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 0.768448 ]
        PhyOp_Range TBL: Production.TransactionHistory(alias TBL: TH)
        [ Card=113443 Cost(RowGoal 0,ReW 0,ReB 0,Dist 0,Total 0)= 0.713995 ]
        ScaOp_Comp x_cmpEq
           ScaOp_Identifier QCOL: [TH].Quantity
           ScaOp_Const TI(int,ML=4) XVAR(int,Not Owned,Value=100)
     ScaOp_Const TI(bigint,Null,ML=8) XVAR(bigint,Not Owned,Value=29)
     ScaOp_Const TI(bigint,ML=8) XVAR(bigint,Not Owned,Value=0)

Tất cả RowGoal các thuộc tính hiện được đặt thành 0, cho biết không có mục tiêu hàng. Xml showplan SQL Server 2017 CU3 chứa:

<RelOp NodeId="0" PhysicalOp="Top" EstimateRows="29">
    <RelOp NodeId="1" PhysicalOp="Filter" EstimateRows="29">
        <RelOp NodeId="2" PhysicalOp="Clustered Index Scan" EstimateRows="113443" EstimatedRowsRead="113443">
        </RelOp>
    </RelOp>
</RelOp>

Sự vắng mặt của bất kỳ Ước lượngRowsWithoutRowGoal ở đây chỉ ra rằng không có mục tiêu hàng nào được đặt.

Tóm tắt và Kết luận

Có nhiều cách để một kế hoạch thực hiện bị ảnh hưởng bởi một hoặc nhiều mục tiêu hàng trong các lĩnh vực khác nhau của kế hoạch. Đôi khi, hiệu ứng mục tiêu hàng sẽ có lợi, mang lại số lượng hàng được yêu cầu với độ trễ thấp và hiệu quả cao. Trong những trường hợp khác, ảnh hưởng của mục tiêu hàng có thể dẫn đến các vấn đề về hiệu suất.

Không phải lúc nào bạn cũng có thể biết liệu một mục tiêu hàng có ảnh hưởng đến việc lựa chọn kế hoạch của trình tối ưu hóa hay không chỉ đơn giản bằng cách xem văn bản truy vấn T-SQL. Điều ít được hiểu rõ nhất về các nguyên nhân có thể có của mục tiêu hàng có lẽ là sự hiện diện của kết nối bán hoặc kết nối chống, điều này tôi sẽ nói chi tiết hơn về vấn đề này.

Trước SQL Server 2017 CU3, không có cách nào thực sự đáng tin cậy để phát hiện mục tiêu hàng, ít nhất là không dùng đến các cờ theo dõi không có tài liệu (và biết cách đối sánh và diễn giải đầu ra). Thuộc tính showplan mới sẽ rất hữu ích cho những người đang chạy phiên bản đủ gần đây và nó sẽ hữu ích hơn nữa khi các công cụ khách hàng được cập nhật để hiển thị nó. Hy vọng rằng cải tiến này cũng sẽ được cung cấp cho các phiên bản cũ hơn.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. So sánh SQL, trình tạo truy vấn và ORM

  2. Làm việc với Dữ liệu JDBC không phải ASCII trong Talend

  3. Bất ngờ về Hiệu suất và Giả định:DATEADD

  4. Hekaton with a twist:In-memory TVPs - Part 3

  5. Cải thiện hỗ trợ cho việc xây dựng lại số liệu thống kê song song