我目前正在将一些数据导入到遗留系统中,并发现该系统不使用单个聚集索引。一个快速的谷歌搜索向我介绍了 HEAP 表的概念,现在我很好奇在什么使用场景中 HEAP 表应该比集群表更受欢迎?
据我了解,HEAP 表仅对审计表和/或插入发生的频率远高于选择的情况有用。它将节省磁盘空间和磁盘 I/O,因为没有要维护的聚集索引,并且由于非常罕见的读取,额外的碎片不会成为问题。
对于具有标识列的表,是否应该为标识列创建聚集或非聚集 PK/唯一索引?
原因是将为查询创建其他索引。使用非聚集索引(在堆上)并返回索引未涵盖的列的查询将使用较少的逻辑 I/O (LIO),因为没有额外的聚集索引 b 树查找步骤?
create table T (
Id int identity(1,1) primary key, -- clustered or non-clustered? (surrogate key, may be used to join another table)
A .... -- A, B, C have mixed data type of int, date, varchar, float, money, ....
B ....
C ....
....)
create index ix_A on T (A)
create index ix_..... -- Many indexes can be created for queries
-- Common query is query on A, B, C, ....
select A, …
Run Code Online (Sandbox Code Playgroud) performance sql-server database-internals index-tuning heap performance-tuning
受这篇文章的启发:https : //twitter.com/#!/ SQLChicken/status/ 102930436795285505
堆:它们被认为是索引结构还是严格来说是没有索引的表结构?
以下是Microsoft Docs 中的一段:
在堆重建之前,作为 DML 操作的一部分在堆中分配的新页面不会使用 PAGE 压缩。通过移除和重新应用压缩,或者通过创建和移除聚集索引来重建堆。
我不明白为什么会这样。如果我有一个具有指定压缩设置的堆,为什么不将它应用于属于该表的页面?
谢谢
我最近发现一个堆表有超过 70% 的碎片。所以我决定做一个
ALTER TABLE dbo.myTable REBUILD
Run Code Online (Sandbox Code Playgroud)
有趣的是,之后我有 20% 的碎片。从那以后,那张桌子上再也没有写过。所以我决定再做一次重建。
第2次后桌帽50%碎片化就更厉害了! 我真的不明白这怎么会发生......
这是一个有点尴尬的问题,我不敢相信我已经错过了这么多年。
我有一个包含 401 个堆表的供应商第三方数据库。我最近开始使用 Brent Ozar 的脚本并设置sp_BlitzFirst
为每 15 分钟运行一次以收集等待统计信息等。
它发现的是每次运行 24 小时期间,它都告诉我修复转发记录。可能会让一些读者感到震惊的是,我在 DMV 上运行了一个查询,并取回了一些包含超过 150,000 个转发记录值的表。
我明白要解决这个问题是在整个表中有一个聚集索引,或者作为运行ALTER TABLE [tablename] REBUILD
.
然而,我无法找到的是这是否会使表脱机,以及在运行此命令之前我是否应该注意其他任何问题。
我正在使用 2008 R2 的企业版,我想知道以这种方式运行它是否会消除中断的需要?
ALTER TABLE [tablename] REBUILD WITH (ONLINE = ON);
Run Code Online (Sandbox Code Playgroud)
有人对这个有经验么?
sql-server maintenance sql-server-2008-r2 heap online-operations
我有一个大约有 1.500.000 行的日志记录表,主键是一个升序标识,聚集索引在主键上。标识值是自动生成的 => 记录总是添加在最后。平均行大小为 1570 字节。
由于频繁添加新行,因此有很多页面拆分。没有行被更新/删除,并且表上有一个非聚集索引,因此可以选择行。由于页面拆分,聚集索引总是碎片化 > 65%。
我想知道我的表是否会因删除聚集索引并使其成为堆表而受益?
这是我的表 + 非聚集索引的样子:
CREATE TABLE [dbo].[LogEntry](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Application] [varchar](20) NOT NULL,
[EntityFullName] [varchar](80) NOT NULL,
[Action] [int] NOT NULL,
[UserName] [varchar](25) NOT NULL,
[TimeStamp] [datetime] NOT NULL,
[EntityId] [varchar](50) NOT NULL,
[WhatChanged] [nvarchar](max) NULL,
CONSTRAINT [PK_LogEntry] PRIMARY KEY CLUSTERED(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY] )
ON [PRIMARY] …
Run Code Online (Sandbox Code Playgroud) sql-server clustered-index index-tuning heap sql-server-2012
BOL 似乎将堆定义为没有聚集索引的表。
但是许多在线帖子似乎将堆等同于没有任何索引的表。
有什么我不知道的微妙之处吗?
谢谢
我有这张桌子:
CREATE TABLE [dbo].[relatea] (
[mid] [varchar](16) NOT NULL,
[sid] [varchar](16) NOT NULL
)
Run Code Online (Sandbox Code Playgroud)
它存储哈希匹配。将其作为堆有什么好处吗?它有大约 700 万行,并且值在任一列中都不是唯一的。我知道堆通常对任何大表都不好。此表当前没有索引。
我正在考虑将表格更改为:
CREATE TABLE [dbo].[relatea] (
[mid] [varchar](16) NOT NULL,
[sid] [varchar](16) NOT NULL,
CONSTRAINT [pk_relatea] PRIMARY KEY CLUSTERED (
[mid] ASC,
[sid] ASC
)
)
Run Code Online (Sandbox Code Playgroud)
表的查询一般但不总是在sid
和组合mid
,并sid
应始终是唯一的。
与将表保留为堆相比,创建这样的聚集索引是否更好?
我在我们的一个生产数据库中有大约 40 个表,由于各种原因,这些表不是使用聚集索引创建的。
转换这些堆的最佳自动化方法是什么?
由于我天生是一名开发人员,我真的不想手动执行此操作。
我开始为此创建一个过程,如为什么此游标以不正确的顺序产生结果中所述?,然而我对那篇文章的回应让我怀疑我在做什么。