假设我有一个看起来像这样的表:
CREATE TABLE Activity (
ActivityID int primary key identity(1,1) ,
ActivityName nvarchar(10),
InactiveFlag bit
)
Run Code Online (Sandbox Code Playgroud)
具有如下所示的索引:
CREATE INDEX Activity_Index on Activity
(
ActivityName
)
Run Code Online (Sandbox Code Playgroud)
然后出于某种原因,有人创建了第二个索引:
CREATE INDEX Another_Activity_Index on Activity
(
ActivityName, InactiveFlag
)
Run Code Online (Sandbox Code Playgroud)
删除第一个索引绝对安全吗?它只是占用了不必要的磁盘空间吗?第二个索引会覆盖第一个索引的所有情况吗?列排序绝对是“ActivityName”第一。
我正在尝试在两个表之间进行单列合并。第一个表 ( VisitorSession) 有 40,000,000 行。第二个 ( ShoppingCart) 有 9,000,000 行。
在我的开发环境中,查询只需不到 8 分钟。但是在生产环境中,它应该占用更少(更强大的机器)。但是,我预计该查询至少需要 2 分钟才能在生产中运行。我知道这个查询会导致开发环境中的其他开发人员超时,这意味着它很容易导致客户超时。是否有更安全和/或更快的方法来执行此查询?
declare @dt datetime = cast(dateadd(month, -6, getdate()) as date);
merge ShoppingCart as TargetTable -- 07:55 to complete in Dev
using
(
select * from -- 04:55 to run select, resulting in 12,727,927 rows in Dev
(
select
visitorid -- int, not null, foreign key
,useripaddress -- varchar(55), null
,row_number() over
(partition by visitorid order by createdate desc) as [row]
from VisitorSession (nolock) …Run Code Online (Sandbox Code Playgroud) 我是一位经验丰富的 SQL Server DBA,但不熟悉分区,我有几个问题。使用 SQL Server 2008 R2 企业版。
我继承了一个每天增长约 10 GB 的大型客户指标数据库。该数据库目前由一个文件组 (PRIMARY) 中的一个大数据文件组成。所有表都有一个名为 的日期时间列InsertedDate。我想对数据进行水平分区InsertedDate,每个日历周使用一个单独的数据文件。
在测试环境中,我将所需的附加文件组和数据文件添加到该数据库中,InsertedDate在每个表中放置了聚集索引,并设置了分区功能和分区方案。通过查询sys.partitions和其他系统表,我确认数据现在物理上驻留在正确的分区和数据文件中。
其中,目标是:
通过仅备份PRIMARY当前日期范围内的文件组和文件组来减少备份时间(我目前正在运行每晚完整备份)。一旦日期范围过去,该分区将永远不会被再次写入,因此我想将文件组设置为只读并最后一次备份它。
能够最终使分区“停止服务”。3 个月后,不再需要将旧数据保持在线,因此我想将这些数据离线(但如果需要,可以再次将这些数据重新在线)。
问题:
1) 如何在不备份整个数据库的情况下对这个分区数据库执行备份?我可以备份单个文件组,但要恢复它需要数据库的其余部分,这违背了使用多个较小数据文件的目的。
2) 如何使分区停止服务?我读过关于切换的内容,但似乎只有当您想在同一数据库内的分区之间移动数据时才有效。我希望能够简单而安全地将一系列数据脱机(并在必要时将其重新联机)。
我的数据库设置了我们所说的临时表和活动表。目前,我们有大约 200 万行用于名为 products 的表。我们称为制造商的客户将他们的数据加载到临时表中,当他们完成更新、添加、删除数据时,我们会将这些数据推送到我们的实时表中。
这些实时表格为移动应用程序和网站提供网络服务。将数据从 staging 推送到 live 包括删除 live 表中的所有数据和插入 staging 表中的所有数据。所有这些都由ManufacturerID存在于每个表中的一个名为的列分隔。
有些制造商有 500 种产品,有些制造商有 75,000 种产品。基于这一点,我们有时会因为对所有 200 万条记录进行分页而导致 Web 服务响应非常缓慢。从实时表中删除数据似乎也变得非常缓慢。
通过ManufacturerID帮助这种情况来分区我的产品表吗?从我读到的内容来看,这基本上意味着当我查询我的产品时,我只会查询数据库的一小部分,ManufacturerID因此整体响应时间有了巨大的改善。
序言:总的来说,这是一个很大的禁忌,但相信我,在真正需要空间的情况下,这种情况很少见。例如 Express Edition 限制为 10GB。想象一下,您发现通过数据类型转换(blob 列)可以释放大量空间。但在那之后,DB 文件的大小仍然和我们知道的一样,10GB 的限制也没有神奇地改变。所以需要某种收缩。那是一个例子。
在我的测试环境中,我执行了:
DBCC SHRINKFILE (DBFile, NOTRUNCATE)
DBCC SHRINKFILE (DBFile, TRUNCATEONLY)
Run Code Online (Sandbox Code Playgroud)
这确实有效(我知道这会最大限度地减少可用空间,在现实世界中我会留下可用空间)。花了很多小时才完成。正如我们所知,它是一个单线程进程奇怪的行为 DBCC Shrinkfile,“它作为一系列非常小的系统事务工作,因此没有什么可回滚的。” - 保罗兰达尔http://www.sqlservercentral.com/Forums/Topic241295-5-1.aspx。我们也知道它搞乱了索引碎片时间http://www.mssqltips.com/sqlservertip/2055/issues-with-running-dbcc-shrinkfile-on-your-sql-server-data-files/和我可以确认。尽管在http://www.karaszi.com/SQLServer/info_dont_shrink.asp 中有描述,但我没有遇到日志文件增长
我发布了一些INDEX REBUILD,REORGANIZE而那些在几秒钟内就完成了。
我的问题:
DBCC SHRINKFILE (DBFile, NOTRUNCATE)所以我只需要DBCC SHRINKFILE (DBFile, TRUNCATEONLY)吗?我有一种感觉,两者在不同的逻辑层面上工作,但我不得不问这个。底线:我保证我不会定期收缩或做任何事情。但这是一个上限被击中并需要收缩的情况。
回答我的第二个问题:我没有遇到事务日志文件增长,因为我在开发人员测试环境中摆弄。事务日志文件会在生产环境中增长(假设完全恢复模型)。您也应该在您的测试环境中模仿它。tr 日志文件的增长实际上大于您可以在数据库文件中释放的空间。最后,您不仅要收缩数据库文件,还要收缩事务日志(如何以及何时这样做取决于恢复模型)。我看到的生产环境有如此严重的索引碎片,它可以变得更好。我的脚本重新索引每个碎片级别高于 30% 的索引。
为了应对增长,您可能必须在进行一生一次的转换时从完全恢复切换到简单。但这会破坏备份链。
回答我的第三个问题:在 DB 文件收缩后进行重新索引/索引重建,因为收缩会弄乱索引碎片。
我还没有试验过所有这些如何影响查询统计信息。
脚本重新索引:见实施例d的TechNet sys.dm_db_index_physical_stats(的Transact-SQL) 。一篇关于增量收缩的文章,会引出其他有价值的内容:http : //www.mssqltips.com/sqlservertip/3178/incrementally-shrinking-a-large-sql-server-data-file-using-powershell
我有一个使用以下 T-SQL 创建的表:
CREATE TABLE [dbo].[TableName](
[id] [int] IDENTITY(1,1) NOT NULL
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
我今天查看了这张表,注意到 id 列正在跳过值:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26、27、1027、1028、1029、1030、1031、1032、1033、1034、1035、2034、2035、3034
我不担心这个或任何事情(我的应用程序不关心主键是什么),我只是想知道可能导致这种情况发生的原因。似乎确实有一种模式,每次“跳跃”发生时跳跃 1000。
我的应用程序使用实体框架插入这些行,如果这有什么不同的话。
sql-server entity-framework auto-increment identity sql-server-2012
我正在处理一个死锁问题。
进程 A 正在对 TableA 执行简单的 INSERT,它对 TableB 有一个 FK
进程 B 正在对包含 TableA 和 TableB 的连接执行复杂的 SELECT
我将在下面包含跟踪信息,但基本上我认为正在发生的是由于 TableA 对 TableB 具有 FK,因此对 TableA 的插入导致了 TableB 的 Primany INDEX 上的排他锁 (X)。我们确实为那个 FK 启用了参照完整性,但是不需要通过插入到 TableA 来更新 TableB,所以我觉得奇怪的是,只需要一个排他锁来检查 FK 值的存在。
这是预期的行为吗?如果是这样,我可以做些什么来减轻这种情况?老实说,我没想到这样一个基本/香草插入会导致僵局。
此外,这不是我真正的问题,但如果您碰巧知道“子资源=满”意味着什么,我会很想知道。
编辑:只是要清楚僵局:
processInserting 正在插入到 TableA 并且在 TableB 上的主索引(TableA 的外键)上有一个 X 锁。ProcessSelecting 正在等待对该索引的 RangeS-S 锁定。
processSelecting 从包括 TableA 和 TableB 在内的许多表的连接中进行选择,并且在 TableA 上有一个 S 锁(因为它正在连接它)。ProcessInserting 正在等待此表上的 IX 锁。
编辑 2:提供更多细节。我正在调用 processSelecting 的“选择”查询是一个非常折磨人的查询,它使用一个折磨人的视图作为连接的一部分,所以看起来有点混乱。
这是 RoutePlan (TableA) 和 Form (TableB) 表的 DDL。
我有一个带有主键 (GUID) 的大表,它也是聚集索引。已经有一个基于整数序列的字段。所以我想保留 GUID 作为 PK 并使整数列成为聚集索引。
除了删除原始约束并创建新的 PK 和新的聚集索引之外,我想不出任何方法来做到这一点。但这需要很长时间,从我收集的内容来看,重建表两次,一次是从聚集索引转到堆,然后堆回到聚集索引。
我无法进行表重建(创建新的、迁移数据、交换名称),因为我不能中断。
有任何想法吗?
版本:SQL Server 2008 Service Pack 2,开发人员/企业。
index sql-server-2008 database-design sql-server clustered-index
由于我无法控制的原因,我必须找到解决此问题的方法。简单地重新安装实例并不是一个选择。在 sys.servers 中显示为 server_id 0 的服务器名称仍显示旧的服务器名称。
运行以下命令时出现错误:
sp_dropserver 'OLD_INSTANCE'
GO
sp_addserver 'NEW_INSTANCE', Local
GO
Run Code Online (Sandbox Code Playgroud)
错误信息:
消息 15190,级别 16,状态 1,过程 sp_dropserver,第 67 行
服务器“OLD_INSTANCE”仍有远程登录或链接登录。
消息 15028,级别 16,状态 1,过程 sp_addserver,第 87 行
服务器“NEW_INSTANCE”已存在。
最奇怪的是,远程登录是“空”登录。
exec sp_dropremotelogin @remoteserver = 'OLD_INSTANCE'
go
Run Code Online (Sandbox Code Playgroud)
错误信息:
消息 15185,级别 16,状态 1,过程 sp_dropremotelogin,第 70 行
没有从远程服务器“OLD_INSTANCE”映射到本地用户“(null)”的远程用户“(null)”。
旧实例不存在登录信息。
sp_helpremotelogin 'OLD_INSTANCE'
Run Code Online (Sandbox Code Playgroud)
消息 15201,级别 16,状态 1,过程 sp_helpremotelogin,第 37
行 远程服务器“OLD_INSTANCE”没有远程登录。
如果无法删除不存在的登录名,如何重命名该实例?有没有办法刷新登录信息?
在 VM 上配置新的 SQL Server 时,最好将数据库、TempDB、日志和备份放在单独的逻辑驱动器上,即使底层存储相同?我知道这在物理服务器上是一个很好的做法;这种分离实际上帮助我们减少了并发 I/O 带来的痛苦。
我试图了解拥有 3 个驱动器而不是 5 个驱动器是否有意义。有人可以提供他们对这个想法的看法/建议吗?
sql-server best-practices storage configuration sql-server-2014
sql-server ×10
index ×2
partitioning ×2
deadlock ×1
foreign-key ×1
identity ×1
index-tuning ×1
instance ×1
locking ×1
merge ×1
optimization ×1
shrink ×1
storage ×1