我们正在使用基于 SQL Server 2005 的专有应用程序,它有许多基于 HEAP 的表(即没有聚集索引)。多年来,这些表变得非常碎片化(例如 99% 碎片化)。我需要对它们进行碎片整理。
现在,在 SQL Server 2005 中,没有办法直接做到这一点。我可以:
现在,这是一个由供应商编写的大型应用程序——一个巨大的黑匣子。我并不急于弄乱他们的东西。我不太了解这些表是如何使用的。这样做的影响最小的方法是什么?
而且,作为后续:有许多这些基于 HEAP 的表,应用程序使用了十多个数据库。有没有办法自动选择 #2 或 #3?或者,我应该如何选择要修改的表?
更新:
回答(非常有帮助的)回复提出的问题:
简而言之,客户支持团队已经明确表示:您必须对表格进行碎片整理,如何做是您的事。
至于未来的版本:是的,新版本正在开发中,最终会迁移到 SQL Server 2012。但是他们今天需要性能解决方案。
最后,至于碎片整理时间太长:没关系。他们有 99% 碎片化的巨型表;该应用程序不在夜间使用;我可以轻松地一次花费数小时对它们进行碎片整理。
performance sql-server optimization clustered-index index-tuning
碰巧我不得不同时使用 SQL Server 和 Oracle 很长一段时间(幸好不是同时使用)。
仍然让我困惑的是将表存储为平衡树的方法。在类似 Oracle 的 RDMS 堆中是默认的,在 SQL Server(和许多其他)中,相反(集群,IOT)是真实的。每种方法的专家都声称他们的方法是唯一“正确”的,并支持通过大量测试/演示选择的观点。但是,在我看来,他们证明的唯一一点是“非默认”方法的实施很差,并且不应该用于大多数情况......
我很确定这两种方法都足够好(只是因为它们仍然存在于市场上并且表现出相当的性能)并且下面有一些数学运算,但是我没有找到任何好的参考。
我意识到这个话题可能太宽泛而无法回答,非常欢迎好的链接,但我真的很想知道为什么两种看似有争议的方法都证明它们都是有效的。
我有一个大(6db)的跟踪表。它有一个通过 GETDATE() 创建的聚集键 (DateTime)。
连接到这个数据库/表的连接池在 10 台计算机的集群中平均上升到 50,因此平均我们有大约 500 个并发连接尝试插入。
数据库适合内存,几乎看不到任何 IO。
我试图弄清楚在持续的 INSERT 负载下,聚集索引是否会达到重新平衡树的程度,以及这是否会导致系统可以维持的插入次数减慢。
关于重新平衡索引是否是 SQL Server 对聚集索引(甚至是非聚集索引)执行的操作,我有一些疑问。
问题-
其他信息
performance sql-server clustered-index insert nonclustered-index
我被要求查看一张非常繁忙的表格并找出任何需要改进的地方。
我只能更改索引表的能力非常有限。
sys.dm_db_index_usage_statsDMV,在过去 7 周内每周运行两次。此表上的当前聚集索引有五列:
我的理解是聚簇索引应该坚持以下属性。 来源
当前的聚集索引不是这些。
所以我的假设是用Id列上的聚集索引来纠正这个问题- 一个不是身份但通过计数器表维护的整数(读取值,加 1,更新计数器表)。
我在 上创建了一个聚集索引Id,不使用主键,因为我相信添加 guid 和 company 列不会给我任何好处。
然后我创建了一个非聚集索引,其中包含 …
我有一个大约有 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
我有一个带有主键 (GUID) 的大表,它也是聚集索引。已经有一个基于整数序列的字段。所以我想保留 GUID 作为 PK 并使整数列成为聚集索引。
除了删除原始约束并创建新的 PK 和新的聚集索引之外,我想不出任何方法来做到这一点。但这需要很长时间,从我收集的内容来看,重建表两次,一次是从聚集索引转到堆,然后堆回到聚集索引。
我无法进行表重建(创建新的、迁移数据、交换名称),因为我不能中断。
有任何想法吗?
版本:SQL Server 2008 Service Pack 2,开发人员/企业。
index sql-server-2008 database-design sql-server clustered-index
假设我有一个Student像这样的人为表:
CREATE TABLE Student (
Id IDENTITY INT,
SchoolId INT NOT NULL,
FirstName VARCHAR(20) NOT NULL,
LastName VARCHAR(20) NOT NULL
)
Run Code Online (Sandbox Code Playgroud)
本能地,我会制作Id主键(以及聚集索引)。但是,我会发现自己在搜索,SchoolId因此我会在SchoolId.
这与主键(和聚集索引)相比如何SchoolId, Id?我将始终拥有SchoolIdif 我需要搜索 by Id,所以无论如何我都会使用聚集索引,如果我只需要搜索 by SchoolId,记录将在物理上彼此相邻。
如果我要进行任何类型的搜索或批量更新,它们会在SchoolId特定记录上,例如找到所有带有姓名/号码/任何内容的孩子SchoolId。我永远不会SchoolId在同一事务中跨多个s执行这些类型的操作。让这些记录在物理上彼此相邻的好处是否使这种方法比简单地在 上使用聚集索引要好得多Id?
使用后者有很大的缺点吗?我还是个新手,有很多主题我还没有完全理解(例如碎片化)以及它如何影响这种情况。
sql-server clustered-index index-tuning physical-design nonclustered-index
过去,我选择创建的datetime列作为表中不合适的聚集索引。
现在我得出结论(基于执行计划)选择 ID身份主键作为聚集键会更好,因为它经常被作为外键引用。
我想删除当前的聚集键并创建一个新的,但我不能删除主键,因为full-text索引依赖于该主键。
我可以将主键切换为聚集索引还是需要删除主键和所有依赖对象的链?
下面你会找到表定义和聚集索引定义。
CREATE TABLE [dbo].[Realty](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Created] [datetime] NOT NULL,
....
CONSTRAINT [PK_Realty] PRIMARY KEY NONCLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
...
CREATE CLUSTERED INDEX [Created] ON [dbo].[Realty]
(
[Created] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE …Run Code Online (Sandbox Code Playgroud) foreign-key sql-server primary-key clustered-index full-text-search
该表确实有一个身份密钥(当前 CI),但它几乎不用于查询。因为自然键不会不断增加,所以我担心插入性能、碎片或其他我现在无法预见的问题。
桌子并不宽,只有几列。它有大约 800 万行,并且在高峰时段使我们的网站停止运行。(+1000s 并发用户)。数据不容易缓存,因为它非常不稳定并且必须保持最新状态。
自然键的一列有很多读取,但插入和更新也相当活跃。说 8 次读取,1 次更新 vs 1 次插入。
Id (PK) int
UserId* int
Key1* varchar(25)
Key2* varchar(25)
Key3* int
LastChanged datetime2(7)
Value varchar(25)
Invalid bit
* this combination is the natural primary key
Run Code Online (Sandbox Code Playgroud)
我大部分时间都需要查询:
我知道最终的答案总是“描述它”,但我们在这里的时间非常有限,因此我们非常感谢您提前提供任何指导或有经验的意见。
提前致谢,
我正在尝试在 Azure SQL 数据库上重建大表 (77GB) 的聚集索引。表上有高并发事务活动,因此我正在使用该ONLINE=ON选项。
这对于较小的表很有效;但是,当我在这个大表上运行它时,它似乎在表上使用了排他锁。我不得不在 5 分钟后停止它,因为所有事务活动都超时了。
来自 SPID 199 的会话:
ALTER INDEX PK_Customer ON [br].[Customer]
REBUILD WITH (ONLINE = ON, RESUMABLE = ON);
Run Code Online (Sandbox Code Playgroud)
从另一个会话:
在相同的结果中更进一步:
我知道在线重建可以在过程开始和结束时锁定“短”持续时间。但是,这些锁定会持续几分钟,这并不完全是“短”持续时间。
在重建运行时,我运行了SELECT * FROM sys.index_resumable_operations;但它返回了 0 行,就好像重建根本没有开始一样。
较小的表也有一个可能大于 900 字节的 PK,并且相同的ALTER语句在没有任何长时间阻塞的情况下工作,所以我认为它与 PK 大小无关。这些较小的表也有相似数量的nvarchar(max)列。我能想到的唯一真正的区别是这个表有更多的行。
这是 的完整定义br.Customer。没有外键或非聚集索引。
CREATE TABLE [br].[Customer](
[Id] [bigint] NOT NULL,
[ShopId] [nvarchar](450) NOT NULL,
[accepts_marketing] [bit] NOT NULL,
[address1] [nvarchar](max) MASKED WITH …Run Code Online (Sandbox Code Playgroud) sql-server clustered-index azure-sql-database index-maintenance online-operations
clustered-index ×10
sql-server ×9
index-tuning ×4
performance ×3
foreign-key ×1
heap ×1
index ×1
insert ×1
optimization ×1
primary-key ×1