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 会ProdName在where有条件的列上使用这个索引吗?因为它创建了警告消息。
通常Like运营商不使用索引吗?
创建索引时 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)
警告!最大密钥长度为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)