在 SQL Server 中创建索引时收到警告消息

Ram*_*Ram 2 sql t-sql sql-server indexing sql-server-2012

我有包含两列的表。当我尝试为该NVARCHAR(2000)列创建索引时,它显示如下警告消息:

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

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

Create Table Test
(
     Id Int primary key,
     ProdName Nvarchar(2000)
)
Run Code Online (Sandbox Code Playgroud)

插入了 100 万条记录。

Created index ix_Test on Test(ProdName)
Run Code Online (Sandbox Code Playgroud)

SQL Server 会ProdNamewhere有条件的列上使用这个索引吗?因为它创建了警告消息。

通常Like运营商不使用索引吗?

Luk*_*zda 5

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

对于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.
Run Code Online (Sandbox Code Playgroud)

db<>小提琴演示

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


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

SELECT MAX(DATALENGTH(ProdName))
FROM Test;
-- should be lower than 900
Run Code Online (Sandbox Code Playgroud)

至于第二个问题,只要条件是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
Run Code Online (Sandbox Code Playgroud)