您的位置:首页 > 其它

为文本数据创建索引的更好方法

2013-03-29 11:07 162 查看
· 打印

导读:为文本数据(varchar、nvarchar、char等)创建索引是一种很好的实现更快数据查询的方法。然而,这些索引会给存储索引的磁盘以及服务器内存带来压力。这是因为……
关键词:SQL Server SQL Server设计 创建索引 文本数据
【TechTarget中国原创】

为文本数据(varchar、nvarchar、char等)创建索引是一种很好的实现更快数据查询的方法。然而,这些索引会给存储索引的磁盘以及服务器内存带来压力。这是因为索引上存有大量的数据。

例如,下面这个表:

CREATE TABLE Employee

(EmployeeID INT,

FirstName VARCHAR(50),

LastName VARCHAR(50),

EmailAddress VARCHAR(255))

现在,假设我们要基于EmailAddress域查找数据。那么我们将使用一个非聚簇索引来索引EmailAddress域。如果我们在诸如AMD的公司工作,那么,我们的邮件地址就会相当的短(f.lastname@amd.com)。然而,如果我们在一个像我所工作的公司工作,那么邮件地址就会稍微有点长(flastname@awarenesstechnologies.com)。现在,当我们对这个字段创建索引时,我们就会将整个邮件地址存放到索引上,它就会在这个索引中占用大量的空间;特别相对数值,如一个整数。毫无疑问,如果我们使用一个双字节编码数据类型,那么它的每个字符会需要两个字节的存储空间,而不是只有通常的一个字节。

如果我们需要对系统中带有URL的域创建索引,这也会是一个问题。 由于URL的长度较长,值的长度可能比索引的值所允许的长度要更长些,这样会带来索引存储问题。

我所知道的这个技术有好几种。我最常用的一种是使用CHECKSUM方法作为计算字段的一部分,然后在这个计算字段上创建索引。这样,我们简单地获得我们要查找的字段的CHECKSUM值,然后就可以查找计算字段。现在我们就有一个由整数组成的索引,这个索引可以填入比每个物理数据页更多的数据,从而减少了索引查找的IO开销并节省磁盘空间。

这样,我们的表变成这样:

CREATE TABLE Employee

(EmployeeID INT,

FirstName VARCHAR(50),

LastName VARCHAR(50),

EmailAddress VARCHAR(255),

EmailAddressCheckSum AS CHECKSUM(EmailAddress))

现在,我将不再推荐对每个我们所创建的表使用这个技术。我通常只推荐一个这样的技术,当索引的值不符合索引的范围,或表非常的大并且经常进行查找,因此节省的内存是值得在查询前增加额外的CUP时间用以哈希结果值。

从而这个技术有几个好处。如果我们检查域名称总数,那么有些字符无法正确统计。同样,检查一个Unicode版本的字符串将会得到与同样字符串的非Unicode版本不同的结果。

我们可以从下面这三个SELECT语句看到:

SELECT CHECKSUM(’google.com’), CHECKSUM(’g-oogle.com’)

SELECT CHECKSUM(’google.com’), CHECKSUM(N’google.com’)

SELECT CHECKSUM(N’google.com’), CHECKSUM(N’g-oogle.com’)

我们可以看到在第一个查询中我们获得两个不同的值(分别是1560309903和1560342303)。而对于第二个查询,在Unicode和字符串之间我们获得两个不同的值(分别是1560309903和 -1136321484)。根据第一个查询,我们可能预期在第三个查询中也会获得两个不同的值,但是结果并不是这样。由于Unicode字串“-”似乎并不作为CHECKSUM的一部分,因此两个字符串有相同的CHECKSUM值(-1136321484)。

这个技术的另外一个版本是最近Kevin Kline所讨论的,它使用SQL Server 2005的HASHBYTES方法来获得字段的哈希值并使用它。在他的博客中,他提出将它用于表分割,其实这个技术也可以用在这里。

CREATE TABLE Employee

(EmployeeID INT,

FirstName VARCHAR(50),

LastName VARCHAR(50),

EmailAddress VARCHAR(255),

EmailAddressCheckSum AS HASHBYTES(’SHA1′, EmailAddress)

但是,这会得到一个更长的字符串,从而占用索引更多的空间。然而,如果遇到长的Unicode字符串,那么这将会是一个更好的选择。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: