我有一张这样的表:
create table SomeTable (
tableKey int identity(1,1) not null
, foreignKey int not null
, longDesc nvarchar(max) not null
, shortName varchar(100) null
)
我需要在where子句中使用 shortName :
select
tableKey
from
SomeTable
where
foreignKey = @foreignKey
and shortName = @shortName
并且需要很快 - 这个表有数百万行。我可以将它移到longDesc列上方并看到速度增加吗?我假设只要列的大小恒定,数据库就可以简单地跳转到正确的字节偏移量。跳过varchar列必然会产生某种性能损失,是吗?
或者,如果我制作了longDesc nchar(3784)怎么办? (这应该使每行填充8KB页面)这会增加速度吗?
我看到其中一个answers here暗示订单在使用空间方面很重要,但我不确定这会如何转化为性能。
答案 0 :(得分:4)
为了获得最快的速度,您可以创建一个持久的计算列,如shortNameCrc = checksum(shortName),然后在(foreignKey,checksum(shortName))和include(shortName)上创建索引。然后你会查询 其中foreignKey = foreignKey 和shortNameCrc =校验和(@shortName) 和shortName = shortName
如果SomeTable没有聚集在tableKey上,那么您可能希望将tableKey添加为include列。如果它聚集在tableKey上,那么该值已经存在于覆盖索引中。
填写页面不应该导致速度增加,这将花费您过多的内存使用量和更大的访问磁盘的可能性。对于在同一物理区域中争用率非常高的工作负载,在某些情况下填充页面可能更好。
使shortName char(100)可能比varchar(100)更好。鉴于无限的ram,我怀疑它会是。在现实世界中,它可能取决于平均长度和高速缓存未命中的可能性。
答案 1 :(得分:3)
我可以将它移到longDesc列上方并看到速度增加吗?
没有。 IIRC,nvarchar(max)仅保留占位符/指针与表本身。由于这个原因,实际数据被移到别处。出于同样的原因,更改nvarchar(max)的大小也无济于事。
应该做的是在foreignKey,shortName和tableKey上添加索引。然后索引可以完全满足您的查询。
答案 2 :(得分:2)
要加快此查询,您可以使用覆盖索引( http://www.devx.com/dbzone/Article/29530),也是 (foreignKey,shortName,tableKey) 要么 (shortName,foreignKey,tableKey)
尝试两者并看看哪种能提供更好的性能