【问题标题】:SQL 2005 performance: column order when mixing varchars with int typesSQL 2005 性能:将 varchar 与 int 类型混合时的列顺序
【发布时间】:2010-10-31 03:03:50
【问题描述】:

我有一张这样的桌子:

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 暗示顺序在已用空间方面很重要,但我不确定这如何转化为性能。

【问题讨论】:

    标签: sql-server sql-server-2005 performance


    【解决方案1】:

    为了获得最快的速度,您将创建一个像 shortNameCrc = checksum(shortName) 这样的持久计算列,然后在 (foreignKey, checksum(shortName)) 上创建一个索引并包含 (shortName)。然后你会像这样查询 其中外键=外键 和 shortNameCrc = 校验和(@shortName) 和短名称 = 短名称

    如果 SomeTable 没有聚集在 tableKey 上,那么您需要将 tableKey 添加为包含列。如果它聚集在 tableKey 上,则该值已经存在于覆盖索引中。

    填充页面不应导致速度增加,这将使您消耗过多的内存并增加访问磁盘的可能性。在某些情况下,对于同一物理区域内竞争非常激烈的工作负载,填充页面可能会更好地提高吞吐量。

    制作shortName char(100) 可能比varchar(100) 更好。鉴于无限的内存,我怀疑它会是。在现实世界中,它可能取决于平均长度和缓存未命中的可能性。

    【讨论】:

      【解决方案2】:

      我可以将它移到 longDesc 列上方并查看速度增加吗?

      没有。 IIRC,nvarchar(max) 仅与表本身保持占位符/指针。正是出于这个原因,实际数据被转移到其他地方。出于同样的原因,更改 nvarchar(max) 的大小也无济于事。

      应该做的是在 foreignKey、shortName 和 tableKey 上添加一个索引。那么索引就可以完全满足您的查询。

      【讨论】:

      • 仅供参考 - nvarchar(max) 如果适合则在行内,如果不适合则自动流出行。
      【解决方案3】:

      为了加快查询速度,您可以使用覆盖索引 ( http://www.devx.com/dbzone/Article/29530),或者 (外键、短名称、表键) 要么 (shortName, foreignKey, tableKey)

      两种都试一下,看看哪一种效果更好

      【讨论】:

        猜你喜欢
        • 2013-12-31
        • 1970-01-01
        • 2011-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-17
        • 1970-01-01
        相关资源
        最近更新 更多