标签: sql-server

对于表的大量更改,有什么更好的方法:DELETE 和 INSERT 每次或 UPDATE 存在?

我正在做一个项目,我需要每天在一张表中更改大约 36K 条记录。我想知道什么会表现得更好:

  1. 删除行并插入新行,或
  2. 更新已经存在的行

对我来说,删除所有行并插入新行会更容易,但如果这会使表和索引碎片化并影响性能,那么我更愿意在可能的情况下进行更新并仅在必要时删除/插入。

这将是一项夜间服务,我不希望提高流程本身的速度。我更关心对这个表的查询性能,我已经有 8900 万条记录,以及这个每晚的过程将如何影响它。

对于这个夜间流程,我应该删除/插入记录还是应该更新现有记录(在可能的情况下)?

performance sql-server-2005 sql-server application-design fragmentation

30
推荐指数
4
解决办法
6万
查看次数

Eager 线轴表示什么问题

当前在 SQL Server 2008 R2 上运行

我正在尝试提高 UPDATE 语句的性能。我注意到弹出显示计划中的 Eager Spool 操作。我对假脱机操作的理解非常基本 - 它们在更新期间为表创建临时存储。

我也知道,虽然它们可以防止更糟糕的执行时间,但急切的假脱机通常表明表结构和/或查询语句存在潜在问题。

我的问题很简单:当您在查询计划中看到 Eager Spool 时,您首先要解决哪些问题?

我将分析我们系统的每个部分以提高性能 - 我只是在寻找关于我应该从哪里开始的指导。

sql-server sql-server-2008-r2

30
推荐指数
1
解决办法
4万
查看次数

我应该使用哪种 PowerShell 技术来与 SQL Server 通信?

我最终想使用 PowerShell 来替换我们用于 SQL 实例监视器的旧 KornShell 脚本。但是,我很难让我的大脑围绕 PowerShell 实际与 SQL Server 通信的所有不同方式。不确定这是否是全部,但我可以通过以下 5 种完全不同的方式查询 SQL 服务器的版本:

1. SQLConnection .NET 类

$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=MyServer;Database=Master;Integrated Security=True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = "Select @@version as SQLServerVersion"
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
$DataSet.Tables[0]
Run Code Online (Sandbox Code Playgroud)

2. WMI 提供程序

$sqlProperties = Get-WmiObject 
    -computerName "MyServer"
    -namespace root\Microsoft\SqlServer\ComputerManagement10
    -class SqlServiceAdvancedProperty
    -filter "ServiceName = 'MSSQLSERVER'"
$sqlProperties.VERSION
Run Code Online (Sandbox Code Playgroud)

3. SMO

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | Out-Null
$smo-var = New-Object …
Run Code Online (Sandbox Code Playgroud)

monitoring sql-server powershell

30
推荐指数
1
解决办法
9331
查看次数

删除/插入时同一独占锁定集群键(使用 NHibernate)上的 SQL 死锁

我已经研究这个僵局问题好几天了,无论我做什么,它都以一种或另一种方式持续存在。

首先,一般前提:我们有访问与访问项的一对多关系。

访问项目相关信息:

CREATE TABLE [BAR].[VisitItems] (
    [Id]                INT             IDENTITY (1, 1) NOT NULL,
    [VisitType]         INT             NOT NULL,
    [FeeRateType]       INT             NOT NULL,
    [Amount]            DECIMAL (18, 2) NOT NULL,
    [GST]               DECIMAL (18, 2) NOT NULL,
    [Quantity]          INT             NOT NULL,
    [Total]             DECIMAL (18, 2) NOT NULL,
    [ServiceFeeType]    INT   NOT NULL,
    [ServiceText]       NVARCHAR (200)  NULL,
    [InvoicingProviderId] INT   NULL,
    [FeeItemId]        INT             NOT NULL,
    [VisitId]          INT             NULL,
    [IsDefault] BIT NOT NULL DEFAULT 0, 
    [SourceVisitItemId] INT NULL, 
    [OverrideCode] INT NOT NULL DEFAULT 0, 
    [InvoiceToCentre] BIT NOT …
Run Code Online (Sandbox Code Playgroud)

sql-server deadlock nhibernate

30
推荐指数
1
解决办法
3885
查看次数

SQL Server 是否支持 GREATEST 和 LEAST,如果不支持,常见的解决方法是什么?

回顾这个问题,似乎不需要做很多工作。他们试图用日期扩展范围。在其他数据库中,您只需使用greatestleast..

least(extendDate,min), greatest(extendDate,max)
Run Code Online (Sandbox Code Playgroud)

当我尝试使用这些时,我得到

'least' is not a recognized built-in function name.
'greatest' is not a recognized built-in function name.
Run Code Online (Sandbox Code Playgroud)

这将涵盖任一方向的扩展。

就问题而言,您仍然需要进行排他性范围替换。

我只是想知道 SQL Server 用户如何实现查询模式来模仿leastgreatest功能。

您是否将条件展开到CASE语句中,或者是否存在启用此功能的 Microsoft 的扩展、第三方加载项或许可?

sql-server feature-comparison t-sql

30
推荐指数
6
解决办法
5万
查看次数

为什么扫描比寻找这个谓词要快?

我能够重现一个我认为出乎意料的查询性能问题。我正在寻找一个专注于内部的答案。

在我的机器上,以下查询执行聚集索引扫描并花费大约 6.8 秒的 CPU 时间:

SELECT ID1, ID2
FROM two_col_key_test WITH (FORCESCAN)
WHERE ID1 NOT IN
(
N'1', N'2',N'3', N'4', N'5',
N'6', N'7', N'8', N'9', N'10',
N'11', N'12',N'13', N'14', N'15',
N'16', N'17', N'18', N'19', N'20'
)
AND (ID1 = N'FILLER TEXT' AND ID2 >= N'' OR (ID1 > N'FILLER TEXT'))
ORDER BY ID1, ID2 OFFSET 12000000 ROWS FETCH FIRST 1 ROW ONLY
OPTION (MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)

以下查询执行聚集索引查找(唯一的区别是删除FORCESCAN提示),但需要大约 18.2 秒的 CPU 时间:

SELECT ID1, ID2
FROM two_col_key_test
WHERE ID1 …
Run Code Online (Sandbox Code Playgroud)

performance sql-server database-internals query-performance

30
推荐指数
1
解决办法
2617
查看次数

索引空间大于数据空间是不是很糟糕?

我经常需要对没有正确索引的大表运行查询。所以我要求 DBA 创建这样的索引。他做的第一件事是查看表统计信息并查看索引空间大小。

通常他会告诉我寻找替代解决方案,因为“索引已经大于表”。他觉得索引必须比数据小,因为,他告诉我“你见过书里的索引吗?它比书本身小得多,表索引应该是这样的”。

我不认为他的哲学是正确的,但我不能挑战他,因为他是一名首席 DBA 而我是一名开发人员。我觉得如果一个查询需要一个索引,就应该创建索引,而不是寻找只会使 SP 变得不可读和不可维护的“解决方法”。

我只选择所需的列。问题是我按日期过滤,因此引擎必须进行表扫描以匹配列。该查询每天在晚上运行一次以收集统计信息,但运行需要 15 分钟(我们还有另一个硬性规定:任何过程都不应超过 3 分钟)。

DBA 向我展示了索引统计信息。该表上大约有 10 个索引,其中仅使用了 6 个(统计数据显示其中 4 个的命中率为零)。这是一个有 20 多个开发人员参与的大型系统。无论出于何种原因创建索引,可能不再使用。

我们需要支持 SQL Server 2008,因为这是运行测试数据库的。但客户都在 2014 年和 2016 年。

index sql-server

30
推荐指数
2
解决办法
1万
查看次数

将 SQL Server 实例根目录放在单独的驱动器上有用吗?

我知道在安装 SQL Server 时可以更改许多默认路径,通常在我进行安装时,我会将数据和日志文件夹更改为位于单独的驱动器(通常是 D 和 E)上,但是我最近得到了一个预安装的机器运行的实例名称不是默认的,并且他们已将实例根目录与 mdf 文件一起配置在 D 驱动器上。这意味着在通常只有文件夹和数据库文件的相对干净的驱动器上,我现在也完全安装了 SQL Server 二进制文件。

即我现在有以下内容:

C:\Program Files\Microsoft SQL Server\ --Base Install
D:\Microsoft SQL Server\MSSQL10_50.MyInstance --Instance Binaries
D:\Microsoft SQL Server\MSSQL10_50.MyInstance\MSSQL\DATA --Data Files
E:\Microsoft SQL Server\MSSQL10_50.MyInstance\MSSQL\LOGS --Log Files
Run Code Online (Sandbox Code Playgroud)

通常我会用类似的东西运行:

C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\ --Base Install & Default Instance Binaries
D:\MSSQL\DATA --Data Files
E:\MSSQL\LOGS --Log Files
Run Code Online (Sandbox Code Playgroud)

我可以理解为什么需要一个单独的实例二进制文件夹,但我不明白为什么将所有这些二进制文件放在一个单独的驱动器上会有用。

谁能告诉我为什么这样做可能是合理的?或者也许它根本没有区别?对我来说,它似乎非常不整洁......

sql-server sql-server-2008-r2

29
推荐指数
1
解决办法
7万
查看次数

为什么事务日志在带有夜间备份的简单恢复模式下继续增长

在立即标记为重复之前,我已阅读 Mike Walsh 的《为什么事务日志不断增长或空间不足?,但我认为它没有回答我的情况。我浏览了十几个类似的问题,但相关的问题大多只是说“重复”并指向迈克的问题。

详细信息:我在 SQL Server 2008 R2 上有一堆约 500MB 的数据库,都处于简单恢复模式(不是我的选择),每晚完整备份,包含约 200MB 的数据文件和约 300MB 的日志文件。日志不会立即增长到 300MB,而是在几个月的过程中缓慢增长。至少根据 sp_who2 和活动监视器,它们中的任何一个都没有打开的事务。如果我右键单击数据库并选择属性,它会告诉我有大约 50MB 可用空间。特别是在备份之后,整个日志不应该是免费的吗?在 SIMPLE 模式下,只要没有打开的事务,日志就不应该是免费的吗?

log_reuse_wait_descfromsys.databases说“NOTHING”,根据上面引用的问题和答案说它不应该等待任何东西来重用空间。

如果我做'DBCC SHRINKFILE',日志文件缩小到1MB,所以它愿意回收空间。我可以设置一些每周缩小日志并防止事情失控的东西,但我很困惑为什么 SQL Server 会让我这样做。

我可以理解是否有一些疯狂的事务需要 300MB 来记录它,但我们没有做任何极端的事情,只是基本的 OLTP。来自迈克的问题/答案:

简单恢复模型 - 有了上面的介绍,最容易先讨论简单恢复模型。在此模型中,您是在告诉 SQL Server - 我对您使用您的事务日志文件进行崩溃和重新启动恢复感到满意(您在那里确实别无选择。查找 ACID 属性,这应该很快就有意义),但是一旦您没有不再需要它用于崩溃/重启恢复目的,继续并重用日志文件。

SQL Server 在 Simple Recovery 中侦听此请求,并且仅保留执行崩溃/重新启动恢复所需的信息。一旦 SQL Server 确定它可以恢复,因为数据已加固到数据文件(或多或少),已加固的数据在日志中不再需要并被标记为截断 - 这意味着它会被重新使用。

它一直说日志空间应该被重用,但是随着几个月的缓慢增长,它似乎不是。

我错过了什么?是否有什么原因使 SQL Server 无法将数据识别为“硬化”并释放日志?

(编辑) 行动后报告 - AKA 一点点知识是危险的

在发现这是一个“热门问题”后,我觉得我欠了一个解释 7 个月前发生的事情以及我学到的东西,希望能挽救一些其他人的悲伤。

首先,当您查看数据库的属性时,您在 SSMS 中看到的可用空间是数据文件中的可用空间。您可以通过在数据库上运行以下命令来查看这一点,您会发现 SSMS 报告的可用空间是 FileSizeMB 和 UsedSpaceMB …

sql-server sql-server-2008-r2 transaction-log

29
推荐指数
2
解决办法
5万
查看次数

评估合理缓冲池大小的确定性方法是什么?

我试图想出一种理智的方法来了解max server memory (mb)设置是否合适(应该更低,或更高,或保持原状)。我知道max server memory (mb)应该总是足够低,以便为操作系统本身等留出空间。

我正在查看的环境有数百台服务器;我需要一个可靠的公式来确定缓冲池的当前大小是否合适,因为 RAM 是按分配给每个服务器的 GB 计算的。整个环境都是虚拟化的,分配给 VM 的“物理”RAM 可以轻松地向上或向下更改。

我有一个特定的 SQL Server 实例,我现在查看的 PLE 为 1,100,052 秒,相当于 12.7 天(服务器启动的时间)。服务器的最大服务器内存设置为 2560MB (2.5GB),其中实际仅提交 1380MB (1.3GB)。

我已经阅读了几篇文章,包括 Jonathan Keheyias(帖子)和 Paul Randal(帖子)的另一篇文章,以及其他几篇文章。Jonathan 主张监控每 4GB缓冲池低于 300 的 PLE太低了。对于上面的 SQL Server 实例,300 * (2.5 / 4) = 187导致目标 PLE 非常低,低于 300。此实例具有 290GB 的 SQL Server 数据(不包括日志文件),仅用于集成测试。假设在过去的12天代表该服务器的典型用法的,我想说的max server memory (mb)设置可能会降低。

在规模的另一端,我有另一个 PLE 为 …

sql-server sql-server-2008-r2 sql-server-2012

29
推荐指数
2
解决办法
6596
查看次数