VARCHAR列上的索引

一年前,我写了在索引的导航结构里,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这里已给你一个插入/更新操作会失败的警告:

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

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

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

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/

时间: 2024-10-10 01:11:57

VARCHAR列上的索引的相关文章

SQL Server如何在变长列上存储索引

原文:SQL Server如何在变长列上存储索引 这篇文章我想谈下SQL Server如何在变长列上存储索引.首先我们创建一个包含变长列的表,在上面定义主键,即在上面定义了聚集索引,然后往里面插入80000条记录: 1 -- Create a new table 2 CREATE TABLE Customers 3 ( 4 CustomerName VARCHAR(255) NOT NULL PRIMARY KEY, 5 Filler CHAR(138) NOT NULL 6 ) 7 GO 8

列上加索引时事有条件

在列上加索引时事有条件的:1.经常被查询的列2.order by子句中使用的列3.是外键或者主键的列4.列是唯一的列5.两个或多个列经常同时出现在where子句中或者连接条件中 一般来说,应该在这些列上创建索引: 1在经常需要搜索的列上,可以加快搜索的速度: 2在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构: 3在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度: 4在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的: 5在经常需要排序的列上

非索引列上的统计 <第二篇>

非索引列上的统计 有时候,可能在连接或过滤条件中的列上没有索引.即使对这种非索引列,如果查询优化器知道这些列的数据分布(统计),它也很可能做出最佳的选择. 除了索引上的统计,SQL Server可以在没有索引的列上建立统计.即使不是索引列,当你开启了SQL Server自动创建统计功能,SQL Server就自动在执行WHERE.JOIN等查询列上创建统计.数据分布的信息或者特定值出现在非索引列上的可能性,都能够帮助查询优化器确定最优的处理策略.即使查询优化器不能真正使用索引来定位这些列,这也仍

在计算列中创建索引提高性能

前言:在理解计算列上的索引之前,先了解计算列的基本知识.计算列由可以使用同一表中的其他列的表达式计算得来.表达式可以是非计算列的列名.常量.函数,也可以是用一个或多个运算符连接的上述元素的任意组合.表达式不能为子查询.默认情况下,计算列是一个虚拟的列,并且可以在调用时重新计算,直到在CREATE TABLE或者ALTER TABLE 命令中使用PERSISTED.如果列定义成PERSISTED,会存放计算值,并存放在原始列上更新后的汇总值,不能对计算列进行INSERT.UPDATE. 准备工作:

索引列上的统计 <第一篇>

一.索引在查询优化中的角色 SQL Server的查询优化器是基于开销的优化器.它通过确认选择性.数据的唯一性以及过滤数据(通过WHERE或JOIN子句)所使用的列来决定最佳的数据访问机制.统计与索引一同存在,但是它们也作为断言的一部分存在于没有索引的列上. 作为谓词引用的列中数据分布的最新信息帮助优化器确定所使用的查询策略.在SQL Server中,这个信息以统计的形式维护,这对于基于开销的优化器创建一个有效的查询执行计划是很重要的.通过统计,优化器能做出返回结果集或中间结果集所花费时间的精确

为什麽我们一般会在自增列或交易时间列上建立聚集索引?

http://www.cnblogs.com/lyhabc/p/3533027.html 一般的交易系统里面我们都会以自增列或交易时间列作为聚集索引列,因为一般这些系统都是写多读少 每天的交易数据会不停的插入到数据库,但是读取数据就没有数据插入那么频繁 因为这些系统一般是写多读少,所以我们会选择在自增列或交易时间列上建立聚集索引 测试 测试环境:SQLSERVER2012 SP1  WINDOWS7 64位 我们来做一个测试,测试脚本如下: 1 --测试脚本 插入性能 2 USE [test]

UNIQUEIDENTIFIER列上的统计信息

UNIQUEIDENTIFIER列上的统计信息非常有意思,在它上面有一些很令人讨厌的行为.我们来看下. 问题重现(The repro) 为了向你展示我们刚抱怨的行为,我用下列简单的表定义创建了一个数据库,我在UNIQUEIDENTIFIER列上强制主键约束.这意味着SQL Server在后台会生成唯一聚集索引,聚集索引本身有一个统计信息对象来描述那列的数据分布情况.当然,数据分布是线性的,因为在UNIQUEIDENTIFIER列每个值本身都是唯一的. 1 -- Create a new tabl

外键约束列没建索引导致大量library cache pin/library cache lock

清空一个100多万行的大表的数据,发现一直执行了几个小时: delete B001.T_B11; 通过以下SQL进行跟踪,发现经常会出现library cache pin和library cache lock的等待,怀疑有大量的recursive sql在执行,于是对这个session做了10046: 发现有大量的如下SQL执行,每删除1行T_B11,都会执行下面2条SQL一次, PARSING IN CURSOR #3 len=93 dep=2 uid=0 oct=3 lid=0 tim=14

SqlServer在视图上创建索引的条件

在视图上创建索引需要三个条件: 一.视图必须绑定到架构. 要做到这点,在 CREATE VIEW 语句中,必须加上 WITH SCHEMABINDING,如果是使用企业管理器,则在设计界面的空白处点击右键,属性,选中“绑定到架构”. 二.索引必须是唯一索引.  www.2cto.com 要做到这点,在 CREATE INDEX 中必须指定 UNIQUE. 三.索引必须是聚集索引. 要做到这点,在 CREATE INDEX 中必须指定 CLUSTERED. 例: CREATE VIEW viewF