Chèn với chuyển đổi loại ngầm định gây ra cảnh báo cho ước tính cardinality


7

Tôi nhận thấy điều này trong khi thực hiện một số thử nghiệm hiệu suất gần đây. Khi tôi chèn một giá trị vào một cột sẽ yêu cầu chuyển đổi ngầm định (ví dụ: bigintthành nvarchar), tôi nhận được cảnh báo:

Chuyển đổi loại trong biểu thức (CONVERT_IMPLICIT(nvarchar(50),[tempdb].[dbo].[#MyFunIntTable].[EvenCoolerColumn],0))có thể ảnh hưởng đến "Ước tính Cardinality" trong lựa chọn gói truy vấn.

Là một công dân có liên quan, tôi đã kiểm tra tất cả các nghi phạm rõ ràng và cuối cùng đã đào sâu vào XML để xác nhận rằng đó thực sự là cảnh báo về việc chèn vào bảng. Vấn đề là, tôi không thể hiểu tại sao điều này lại ảnh hưởng đến ước tính tim mạch. Nếu tôi đang làm điều này trong một phép nối hoặc ở một nơi nào đó có logic hơn một chút thì sẽ có ý nghĩa, nhưng không nên có một ước lượng không chính xác cho hoạt động chèn thực tế, phải không?

Tôi nhận thấy rằng điều này xảy ra khi nó không chỉ là một truy vấn tầm thường - ngay khi có nhiều hơn một giá trị được chèn hoặc chúng tôi đang kéo một giá trị từ một bảng, chúng tôi đã nhấn vào đây.

Câu hỏi này đã thu hút một số trùng lặp tiềm năng, bao gồm:

Tôi nghĩ nó khác với những câu hỏi này bởi vì tôi thực sự không làm gì với cột này. Tôi không sử dụng nó trong một bộ lọc, hoặc sắp xếp, hoặc nhóm, tham gia hoặc trong một chức năng - bất kỳ điều nào trong số này làm cho kịch bản phức tạp hơn. Tất cả những gì tôi đang làm là chèn một bigintvào nvarchar, điều này sẽ không bao giờ ảnh hưởng đến ước tính số lượng có ý nghĩa mà tôi có thể nghĩ ra.

Điều tôi đặc biệt tìm kiếm từ một câu trả lời là:

  1. Một lời giải thích về lý do tại sao tôi nhận được cảnh báo này mặc dù không có gì đáng quan tâm - có phải là SQL Server sẽ bảo thủ và báo cáo ngay cả khi nó không ảnh hưởng đến lựa chọn kế hoạch?
  2. Ước tính cardinality nào thực sự có nguy cơ ở đây, và hoạt động nào sẽ thay đổi dựa trên sự không chính xác trong ước tính cardinality đó?
  3. Có một kịch bản mà điều này có thể ảnh hưởng đến sự lựa chọn kế hoạch? Rõ ràng nếu tôi bắt đầu tham gia hoặc lọc trên cột được chuyển đổi thì có thể, nhưng như vậy là gì?
  4. Có bất cứ điều gì có thể được thực hiện để ngăn nó cảnh báo, bên cạnh việc thay đổi loại dữ liệu (giả sử đây là yêu cầu về cách các mô hình dữ liệu tương tác)

Tôi đã tạo lại nó với ví dụ đơn giản dưới đây ( dán kế hoạch )

DROP TABLE IF EXISTS #MyFunStringTable;
DROP TABLE IF EXISTS #MyFunIntTable;

CREATE TABLE #MyFunStringTable
(
  SuperCoolColumn nvarchar(50) COLLATE DATABASE_DEFAULT NULL
);

CREATE TABLE #MyFunIntTable
(
  EvenCoolerColumn bigint NULL
);

INSERT INTO #MyFunIntTable
( EvenCoolerColumn )
VALUES
( 1 ),
( 2 ),
( 3 ),
( 4 ),
( 5 );

INSERT INTO #MyFunStringTable
( SuperCoolColumn )
  SELECT EvenCoolerColumn
    FROM #MyFunIntTable;

INSERT INTO #MyFunStringTable
( SuperCoolColumn )
VALUES
( 1 );

INSERT INTO #MyFunStringTable
( SuperCoolColumn )
VALUES
( 1 ),
( 2 );

INSERT INTO #MyFunStringTable
( SuperCoolColumn )
  SELECT 1;

INSERT INTO #MyFunStringTable
( SuperCoolColumn )
SELECT 1
UNION ALL
SELECT 2;

INSERT INTO #MyFunStringTable
( SuperCoolColumn )
  SELECT 1
    FROM #MyFunIntTable;

Câu trả lời:


9

Giống như các cảnh báo kế hoạch thực hiện khác, đây là thông tin. Nếu truy vấn của bạn thực hiện chậm hoặc bạn nhận thấy rằng ước tính cardinality không chính xác, cảnh báo sẽ cung cấp cho bạn thông tin về nơi cần tìm nguyên nhân có thể.

Là một vấn đề hoàn toàn thực tế, đó là kết thúc của nó. Các điều kiện chính xác kích hoạt cảnh báo tối ưu hóa này là không có giấy tờ.

Điều đó nói rằng, tôi sẽ đi vào một chi tiết nhỏ để đáp ứng một chút tò mò của bạn.

1. Một lời giải thích về lý do tại sao tôi nhận được cảnh báo này mặc dù không có gì đáng quan tâm - có phải là SQL Server sẽ bảo thủ và báo cáo ngay cả khi nó không ảnh hưởng đến lựa chọn kế hoạch?

những điều đang xảy ra quan tâm đến các thành phần dự cardinality của tôi ưu truy vấn. Thành phần này theo dõi một loạt các thuộc tính và thông tin khác cho mỗi toán tử logic trong cây truy vấn. Điều này bao gồm biểu đồ (từ đĩa hoặc xuất phát hoàn toàn trong bộ nhớ), thông tin tên miền, phụ thuộc chức năng, v.v.

Trong ví dụ cụ thể của bạn, cảnh báo được kích hoạt khi đầu vào chuyển đổi được biết là đơn điệu nhưng đầu ra thì không. Chuyển đổi từ integernghĩa đen để bigintgiữ lại tài sản này. Chuyển đổi từ bigintđể nvarchar(50)không.

Khi có một hằng số nguyên duy nhất, hằng số gấp theo thời gian phân tích chuyển đổi này thành nvarchartrước khi bắt đầu tối ưu hóa. Điều này tránh chuyển đổi loại trong kế hoạch và cảnh báo liên quan.

Có sự khác biệt thực hiện nội bộ chi tiết giữa công cụ ước tính cardinality ban đầu và công cụ ước tính cardinality mới có nghĩa là một số báo cáo sẽ tạo cảnh báo theo một CE nhưng không phải là khác.

2. Ước tính cardinality nào thực sự có nguy cơ ở đây, và hoạt động nào sẽ thay đổi dựa trên sự không chính xác trong ước tính cardinality đó?

Trong các tuyên bố ví dụ của bạn, không có. Như đã lưu ý, việc chuyển đổi có thể ảnh hưởng đến dữ liệu nội bộ khác, có thể ảnh hưởng đến các nhà khai thác kế hoạch khác hoặc đường dẫn mã được thực hiện thông qua trình tối ưu hóa. Điểm rộng là có nhiều hơn một ước tính cardinality thô để xem xét. Sự khác biệt bên trong có thể ảnh hưởng đến những thứ như chế độ xem được lập chỉ mục hoặc kết hợp cột được tính toán, trong số các khả năng khác.

3. Có kịch bản nào mà điều này có thể ảnh hưởng đến sự lựa chọn kế hoạch không? Rõ ràng nếu tôi bắt đầu tham gia hoặc lọc trên cột được chuyển đổi thì có thể, nhưng như vậy là gì?

Điều này dường như giống như câu hỏi trước.

4. Có bất cứ điều gì có thể được thực hiện để ngăn không cho nó cảnh báo, bên cạnh việc thay đổi loại dữ liệu (giả sử đây là yêu cầu về cách các mô hình dữ liệu tương tác)

Không có tùy chọn để tắt những cảnh báo này.

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.