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ụ: bigint
thà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 sao tôi nhận được một chuyển đổi ngầm định của Int / Smallint sang Varchar, và nó có thực sự ảnh hưởng đến Ước tính Cardinality không?
- Chuyển đổi loại trong biểu thức có thể ảnh hưởng đến "CardinalityEstimate" trong lựa chọn gói truy vấn?
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 bigint
và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à:
- 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?
- Ướ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 đó?
- 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ì?
- 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;