我的公司使用的应用程序存在严重的性能问题。我正在解决的数据库本身存在许多问题,但许多问题纯粹与应用程序有关。
在我的调查中,我发现有数百万个查询访问 SQL Server 数据库,这些查询查询空表。我们有大约 300 个空表,其中一些表每分钟查询 100-200 次。这些表格与我们的业务领域无关,本质上是原始应用程序的一部分,供应商在与我公司签订合同为我们提供软件解决方案时并未删除这些原始应用程序。
除了我们怀疑我们的应用程序错误日志充斥着与此问题相关的错误这一事实之外,供应商向我们保证,应用程序或数据库服务器不会对性能或稳定性产生影响。错误日志泛滥到我们无法看到超过 2 分钟的错误进行诊断的程度。
就 CPU 周期等而言,这些查询的实际成本显然会很低。但是有人可以建议对 SQL Server 和应用程序产生什么影响吗?我怀疑发送请求、确认请求、处理请求、返回请求和确认应用程序接收的实际机制本身会对性能产生影响。
我们为应用程序使用 SQL Server 2008 R2、Oracle Weblogic 11g。
@Frisbee- 长话短说,我创建了一个包含查询文本的表,该表命中了应用程序数据库中的空表,然后查询它以查找我知道为空的所有表名,并得到了一个很长的列表。最重要的是在 30 天的正常运行时间内执行了 270 万次,请记住,该应用程序通常在上午 8 点至下午 6 点使用,因此这些数字更集中于运行时间。多个表,多个查询,可能有些是通过连接相关的,有些则不是。最大的成功(当时是 270 万)是从一个带有 where 子句的空表中进行简单的选择,没有连接。我希望连接到空表的更大查询可能包括对链接表的更新,但我会检查并尽快更新这个问题。
更新:有 1000 个查询的执行计数在 1043 - 4622614 之间(超过 2.5 个月)。我将不得不进一步挖掘以找出缓存计划的来源。这只是为了让您了解查询的范围。大多数都相当复杂,有 20 多个连接。
@srutzky-是的,我相信有一个与计划何时编译相关的日期列,因此我会感兴趣,所以我会检查一下。我想知道当 SQL Server 位于 VMware 集群上时,线程限制是否会成为一个因素?谢天谢地,很快就会成为专用的戴尔 PE 730xD。
@Frisbee - 抱歉回复晚了。正如您所建议的,我使用 SQLQueryStress(实际上是 240,000 次迭代)在 24 个线程上从空表中运行了 10,000 次 select * 并立即达到了 10,000 批请求/秒。然后我将 24 个线程减少到 1000 次,并达到了不到 4,000 个批处理请求/秒。我还仅在 12 …
COUNT(CASE WHEN [Column A] = ____ THEN 1 END
和 和有COUNT(CASE WHEN [Column A] = ____ THEN 1 ELSE 0 END什么区别?
我一直在使用前者,到目前为止我还没有看到区别;添加的原因是什么ELSE 0- 是否存在 SQL Server 计数错误的情况?
我偶尔会NOLOCK在一些大型作业中遇到“由于数据移动而无法继续扫描”,这些作业WITH (NOLOCK)在选择查询中确实有。
我知道这与在页面拆分导致数据不再位于应有的位置时尝试选择数据有关 - 我认为这就是我的环境中发生的情况。
我将如何重现这个?
我正在尝试做一个短期的解决方法来捕捉错误并在发生这种情况时重试,但如果我无法重现它,我将无法对其进行测试。有没有合理可靠的方法来导致这种情况?
当它发生时,再次执行查询会导致成功 - 所以我真的不担心实际数据或数据库被永久损坏。查询中的一些表(连同它们的索引)经常被删除、重新创建和重新填充,所以我假设它与此相关。
移除NOLOCK是我要处理的长期问题。NOLOCK放在那里的原因首先是查询非常糟糕,以至于它们因日常事务而陷入僵局,因此可以NOLOCK使用创可贴来阻止僵局(有效)。所以我需要一个创可贴,直到我们可以做一个永久性的解决方案。
如果我可以用 Hello World 重现它,我可能会计划在不到一个小时的时间内将创可贴贴到工作中。无法执行搜索和替换删除NOLOCK,因为我会再次开始使应用程序陷入僵局,这对我来说比偶尔失败的工作更糟糕。
使用读提交的快照隔离是一个很好的可能性 - 我将不得不与我们的数据库团队合作以获取更多详细信息。我们的部分问题是我们没有 SQL Server 专家来处理这类事情,而且我对隔离级别的了解还不够充分,无法立即进行更改。
当我使用以下查询监控我的备份时:
SELECT command, percent_complete,
'elapsed' = total_elapsed_time / 60000.0,
'remaining' = estimated_completion_time / 60000.0
FROM sys.dm_exec_requests
WHERE command like 'BACKUP%'
or command like 'RESTORE%'
Run Code Online (Sandbox Code Playgroud)
我注意到在备份之前,SQL Server 只在备份之后执行还原标头。
我想知道它有什么用处,以及它的执行时间是否可以以某种方式减少。它似乎比实际备份花费的时间更长。
有没有办法可以确定计划是为特定查询生成的,还是在计划缓存中找到的?
如何在 SQL Server 2012 中将默认实例转换为命名实例?
我错误地选择了默认实例选项并安装了。现在我必须更改为命名实例。如何改变?
在表中插入值后实时检索最新的guid值
不知道怎么做
CREATE TABLE [AddressBook]
(
[testID] [uniqueidentifier] NOT NULL default newid(),
[address] [nvarchar](50) NULL,
[zipcode] [nvarchar](50) NULL
)
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个用空格替换特殊字符的查询。下面的代码有助于识别行。(字母数字字符、逗号和空格有效):
SELECT columnA
FROM tableA
WHERE columnA like '%[^a-Z0-9, ]%'
Run Code Online (Sandbox Code Playgroud)
如何将替换函数集成到 select 语句中,以便结果集中除字母数字、逗号和空格之外的所有字符都替换为 ' '(空格)。这个不行:
SELECT replace(columnA,'%[^a-Z0-9, ]%',' ')
FROM tableA
WHERE columnA like '%[^a-Z0-9, ]%'
Run Code Online (Sandbox Code Playgroud) 我们的一个用户的名称已合法更改,因此我们更改了他们的 Active Directory 用户名以匹配 - 从域\旧名称到域\新名称。但是,当此用户在存储过程中调用 suser_sname() 时,它返回旧名称,而不是新名称。
谷歌搜索让我找到了KB 946358,这表明他们的名字被缓存在服务器上并且没有更新,大概是因为 suser_name() 正在调用 LsaLookupSids。但是,该文章中的解决方法涉及重新启动服务器,即使是这样,我仍然想了解问题所在。
如果我将上下文更改为他们的上下文,则会返回正确的名称:
EXECUTE AS LOGIN = 'domain\newname'
GO
SELECT suser_name() --returns 'domain\newname'
Run Code Online (Sandbox Code Playgroud)
...我会假设这也会调用 LsaLookupSids,因此会返回不正确的名称。我似乎不太了解这里的工作机制。
一些可能重要的观察结果:
此用户在服务器上没有显式登录。但他们是这样做的 AD 组的成员。更改后的名称 (domain\newname) 出现在结果集中exec xp_logininfo 'domain\ADGroupName', 'members';域\旧名称没有。
用户从存储过程中调用 suser_name(),从 Access 2003 MDB 中的直通查询调用。
过去我们更改了大量用户的帐户名称,但仅在上周才发现此问题(上周进行了两次更改,似乎都出现了此问题)。
服务器在 Windows 2008 R2 数据中心版上运行 Sql Server 2008 SP3 x64。
这是怎么回事?作为 DBA,我可以做什么或者我可以在哪里解决这个问题?
sql-server ×10
t-sql ×2
backup ×1
cache ×1
installation ×1
ms-access ×1
nolock ×1
performance ×1
replace ×1