VARCHAR列上的索引

时间:2021-06-20 16:51:40

一年前,我写了在索引的导航结构里,SQL Server如何存储VARCHAR列。我们都知道,在SQL Server里索引(聚集索引,非聚集索引)的键列有最大900byte的大小限制。

假设现在你想捉弄下SQL Server,在VARCHAR(8000)的列上创建一个索引,并在索引键列上插入超900byte的值。想想,SQL Server会如何反应?不知道?我们来试验下。在下列代码里,我创建了有VARCHAR(8000)列的表,并在这列上创建非聚集索引。

USE TempDb
GO -- Create a simple table
CREATE TABLE Foo
(
Bar VARCHAR(8000)
)
GO -- Create a simple Non-Clustered Index
CREATE NONCLUSTERED INDEX idx_Bar ON Foo(Bar)
GO

SQL Server这里已给你一个插入/更新操作会失败的警告:

VARCHAR列上的索引

现在糟糕的事情发生了:我插入一条901byte大小列的记录。

-- Insert a too large index key column...
INSERT INTO Foo VALUES(REPLICATE('x', 901))
GO

偶滴神——如你所见,现在插入不会发生:

VARCHAR列上的索引

SQL Server还是会确保我们的键大小在900bytes限制内。我们来插入刚好900bytes键大小的记录。

-- This will work
INSERT INTO Foo VALUES(REPLICATE('x', 900))
GO

现在这个会正常运行,没有问题。但如果我们再次更新那列,让它大于900bytes,会发生什么?

-- This UPDATE will fail
UPDATE Foo SET BAR = REPLICATE('x', 901)
GO

UPDATE语句也会失败!这是对的。SQL Server再次保证键大小还是在它限制里。啥收获?不管你怎么折腾,你不会打破SQL Server。

感谢关注!

参考文章:

http://www.sqlpassion.at/archive/2016/04/25/indexes-on-varchar-columns/