代码之家  ›  专栏  ›  技术社区  ›  Ram

在SQL Server中创建索引时获取警告消息

  •  2
  • Ram  · 技术社区  · 7 年前

    我有一张有两列的桌子。当我尝试为 NVARCHAR(2000) 列,它显示的警告消息如下:

    警告!最大密钥长度为900字节

    但索引是在SQL Server中为此表创建的:

    Create Table Test
    (
         Id Int primary key,
         ProdName Nvarchar(2000)
    )
    

    插入了100万条记录。

    Created index ix_Test on Test(ProdName)
    

    SQL Server是否将此索引用于 ProdName 列在 where 条件?因为它是用警告消息创建的。

    通常是这样的 Like 操作员不使用索引?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Lukasz Szozda    7 年前

    创建索引时,SQL Server正在检查列的元数据。SQL Server 2012的最大索引长度为900字节,SQL Server 2016的最大索引长度为1700字节。

    用于 NVARCHAR(2000) 最大字节大小为4000,超过了索引的最大限制。

    Create Table Test(Id Int primary key,ProdName Nvarchar(2000));
    INSERT INTO Test VALUES (1, REPLICATE('0123456789',45));
    Create index ix_Test ON Test(ProdName);
    INSERT INTO Test VALUES (2, REPLICATE('0123456789',46));
    -- Operation failed. The index entry of length 920 bytes for the index    
    --'ix_Test' exceeds the maximum length of 900 bytes.
    

    db<>fiddle demo

    警告!最大密钥长度为 900字节。 索引“ix_test”的最大长度为4000字节。 对于大值的某些组合,插入/更新操作将失败。


    这意味着在您的列中,您有少于450个字符(900字节)的字符串值。

    SELECT MAX(DATALENGTH(ProdName))
    FROM Test;
    -- should be lower than 900
    

    至于第二个问题,只要条件是 SARGable 以下内容:

    SELECT *
    FROM Test
    WHERE ProductName = 'ABC' -- index usage;
    
    SELECT *
    FROM Test
    WHERE ProductName = 'AB%'; -- index usage
    
    SELECT *
    FROM Test
    WHERE ProductName LIKE '%B%'; -- no index seek, index/table scan instead