У меня есть таблица со столбцом VARCHAR
и индекс на нем. Всякий раз, когда SELECT COUNT(*)
выполняется для этой таблицы, которая имеет проверку для COLUMN = N'' OR COLUMN IS NULL
, она возвращает удвоенное количество строк. SELECT *
с тем же условием where
вернет правильное количество записей.
После прочтения этой статьи: https://sqlquantumleap.com/2017/07/10/impact-on-indexes-when-mixing-varchar-and-nvarchar-types/ и проведя некоторое тестирование, я считаю, что сопоставление столбца и неявное преобразование не является ошибкой (по крайней мере, не напрямую). Сортировка столбца: Latin1_General_CI_AS
.
База данных находится на SQL Server 2012, и я также проверил 2016 год.
Я создал тестовый скрипт ( ниже), которая продемонстрирует эту проблему. При этом я считаю, что это может быть связано с подкачкой данных, так как для этого потребовалось немного данных в таблице.
CREATE TABLE [dbo].TEMP
(
ID [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL,
[DATA] [varchar](200) COLLATE Latin1_General_CI_AS NULL,
[TESTCOLUMN] [varchar](50) COLLATE Latin1_General_CI_AS NULL,
CONSTRAINT [PK_TEMP] PRIMARY KEY CLUSTERED ([ID] ASC)
)
GO
CREATE NONCLUSTERED INDEX [I_TEMP_TESTCOLUMN] ON dbo.TEMP (TESTCOLUMN ASC)
GO
DECLARE @ROWS AS INT = 40;
WITH NUMBERS (NUM) AS
(
SELECT 1 AS NUM
UNION ALL
SELECT NUM + 1 FROM NUMBERS WHERE NUM < @ROWS
)
INSERT INTO TEMP (ID, DATA)
SELECT NUM, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901324561234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'
FROM NUMBERS
SELECT @ROWS AS EXPECTED, COUNT(*) AS ACTUALROWS
FROM TEMP
GO
SELECT COUNT(*) AS INVALIDINDEXSEARCHCOUNT
FROM TEMP
WHERE (TESTCOLUMN = N'' OR TESTCOLUMN IS NULL)
GO
DROP TABLE TEMP
Я могу изменить базу данных до некоторой степени (Я не смогу изменить данные или изменить столбец, разрешив NULL
), к сожалению, я не могу изменить код, выполняющий поиск, может ли кто-нибудь определить способ получения правильных COUNT(*)
возвращаемых результатов?