首页 > 解决方案 > 使用空白 NVARCHAR 或 NULL 检查 VARCHAR 索引上的 Count(*) 导致返回的行数翻倍

问题描述

我有一个表,VARCHAR上面有一个列和一个索引。每当SELECT COUNT(*)在此表上执行 a 并对其进行检查时,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(*)结果?

标签: sqlsql-serverindexingcount

解决方案


推荐阅读