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

日期: 2009-03-22 作者:Denny翻译:曾少宁 来源:TechTarget中国 英文

为文本数据(varchar、nvarchar、char等)创建索引是一种很好的实现更快数据查询的方法。然而,这些索引会给存储索引的磁盘以及服务器内存带来压力。这是因为索引上存有大量的数据。 例如,下面这个表: CREATE TABLE Employee (EmployeeID INT, FirstName VARCHAR(50), LastName VARCHAR(50), EmailAddress VARCHAR(255)) 现在,假设我们要基于EmailAddress域查找数据。

那么我们将使用一个非聚簇索引来索引EmailAddr……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

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字符串,那么这将会是一个更好的选择。

作者

Denny
Denny

翻译

曾少宁
曾少宁

TechTarget中国特约技术编辑,某高校计算机科学专业教师和网络实验室负责人,曾任职某网络国际厂商,关注数据中心、开发运维、数据库及软件开发技术。有多本关于思科数据中心和虚拟化技术的译著,如《思科绿色数据中心建设与管理》和《基于IP的能源管理》等。

相关推荐