我们需要每晚在我们的 SQL Server 2008 R2 上做一些报告。计算报告需要几个小时。为了缩短时间,我们预先计算了一个表格。该表是基于 JOINining 12 个相当大(数千万行)的表创建的。
直到几天前,这个聚合表的计算才用了大约 4 个小时。我们的 DBA 将这个大连接拆分为 3 个较小的连接(每个连接 4 个表)。临时结果每次都保存到一个临时表中,供下次join使用。
DBA 增强的结果是,聚合表在 15 分钟内计算完成。我想知道这怎么可能。DBA 告诉我,这是因为服务器必须处理的数据数量较少。换句话说,在大的原始连接中,服务器必须处理比在总和较小的连接中更多的数据。但是,我认为优化器会使用原始大连接有效地执行此操作,自行拆分连接并仅发送下一个连接所需的列数。
他所做的另一件事是在其中一个临时表上创建了索引。但是,我再次认为优化器会在需要时创建适当的哈希表,并更好地优化计算。
我和我们的 DBA 讨论过这个问题,但他自己不确定是什么导致了处理时间的改善。他刚刚提到,他不会责怪服务器,因为计算如此大的数据可能会让人不知所措,而且优化器可能很难预测最佳执行计划...... 我明白这一点,但我想对确切原因有更多明确的答案。
所以,问题是:
什么可能导致大的改善?
将大连接拆分为小连接是标准程序吗?
在多个较小连接的情况下,服务器必须处理的数据量真的更小吗?
这是原始查询:
Insert Into FinalResult_Base
SELECT
TC.TestCampaignContainerId,
TC.CategoryId As TestCampaignCategoryId,
TC.Grade,
TC.TestCampaignId,
T.TestSetId
,TL.TestId
,TSK.CategoryId
,TT.[TestletId]
,TL.SectionNo
,TL.Difficulty
,TestletName = Char(65+TL.SectionNo) + CONVERT(varchar(4),6 - TL.Difficulty)
,TQ.[QuestionId]
,TS.StudentId
,TS.ClassId
,RA.SubjectId
,TQ.[QuestionPoints]
,GoodAnswer = Case When TQ.[QuestionPoints] Is null Then 0
When TQ.[QuestionPoints] > 0 Then 1
Else 0 End
,WrongAnswer …
Run Code Online (Sandbox Code Playgroud) 我试图找出一个简单的查询,我可以做一个简单的查询来测试一个大表是否有一个条目列表,在任何列中至少有一个空白(NULL/空)值。
我需要类似的东西
SELECT * FROM table AS t WHERE ANY(t.* IS NULL)
Run Code Online (Sandbox Code Playgroud)
我不想做
SELECT * FROM table AS t WHERE t.c1 = NULL OR t.c2 = NULL OR t.c3 = NULL
Run Code Online (Sandbox Code Playgroud)
这将是一个巨大的查询。
我正在尝试更改表中的列。现有的表是这样的:
CREATE TABLE [dbo].[table](
[id1] [int] NOT NULL,
[id2] [int] NOT NULL,
[id3] [int] NOT NULL,
[name] [nvarchar](255) NOT NULL,
[id4] [int] NOT NULL,
[xmlData] [xml](CONTENT [dbo].[xml_schema]) NULL,
[booleanData1] [bit] NOT NULL,
[notes] [varchar](4096) NULL,
[id5] [int] NULL,
[booleanData2] [bit] NULL,
[id6] [int] NULL,
CONSTRAINT [PK_table] PRIMARY KEY CLUSTERED
([id1] ASC, [id2] ASC, [id3] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
现在我试图在这个表上执行这个 sql:
ALTER TABLE [table] ALTER COLUMN [xmlData] XML
Run Code Online (Sandbox Code Playgroud)
这样我就可以删除 xml 模式并用新的模式替换它。
但我收到此错误:
无法创建大于允许的最大行大小 8060 的大小为 8074 的行。
谁能告诉我这里有什么问题?
我最近在新的开发机器上安装 Visual Studio 2012 和 SQL Server 2008 R2 时遇到了问题。我的安装顺序是 Visual Studio 2012 然后安装 SQL Server 2008 R2。
SQL Server 安装过程中出现错误:
指定的帐户已存在。
我花了一天的时间试图解决这个问题。
使用以下方法将单个孤立的 SQL 用户修复为登录是相当直接的:
EXEC sp_change_users_login 'Auto_Fix', '用户'
我可以编写这个脚本,但是是否有一个现有的存储过程可以自动尝试修复给定数据库中的每个孤立用户?
我有一些.bak
来自 SQL Server 2005 转储的大文件。
我可以在不使用 SQL Server 的情况下将这些恢复到 PostgreSQL、MySQL 或纯文本文件吗?
开源解决方案将是最有用的。
我们有一个用户即将离开,我需要知道他拥有的每个数据库对象。是否有提供此信息的查询?
我真的很难追踪我们遇到的一些阻塞。
根阻塞的SPID的状态是“睡觉”,在CMD为“命令等待”,而sqltext
为SET TRANSACTION ISOLATION LEVEL READ COMMITTED
。
当我查看 Top Transactions by Blocked Transactions Count 报告时,Blocking SQL Statement 是“--”。
我已经对 SQL 进行了跟踪,当阻塞发生时跟踪根阻塞 SPID,但它并没有真正引导我到任何地方。最后一个 trace 语句与sqltext
上面的相同SET TRANSACTION ISOLATION LEVEL READ COMMITTED
。
我已经检查了我能找到的所有相关存储过程,以确保它们具有 TRY/CATCH BEGIN TRAN/COMMIT TRAN/ROLLBACK TRAN 语句(我们对所有内容都使用存储过程,因此没有运行独立的语句)。这个问题在过去 24 小时内才开始发生,没有人声称对系统进行了任何更改。
解决方案:我们很少使用的存储过程之一在插入时出错(列数不匹配),但我们仍然对到底发生了什么感到困惑。
查看所有跟踪信息时,有时会列出此存储过程的 EXEC 语句,但绝不会在阻塞 SPID 上发生 BLOCK 之前。似乎当它开始阻塞时,跟踪没有记录它的执行(或其中的任何语句)。然而,也有其他时候跟踪确实记录了它的执行并且没有发生阻塞。
存储过程错误报告来自一个用户,我能够在跟踪中找到多个 EXEC 语句并在 SSMS 中运行它们。当我运行它们时,我们没有发生任何阻塞或它们挂起的情况。它们按预期运行(catch 块在错误发生后触发并回滚事务)。解决修复存储过程后,我们没有再看到这个问题。
在查看需要很长时间执行的存储过程列表时,其中一个会引起最多的等待。然而,大部分等待 (81%) 是 ASYNC_NETWORK_IO,我知道原因:存储过程传输大约 400 MB 的信息。
在文档中,它指出 ASYNC_NETWORK_IO 的原因是客户端无法跟上数据的洪流,这可能是真的。我不确定如何让客户端跟上,因为它所做的只是通过 ADO.NET 调用存储过程,然后只处理数据集。
因此,鉴于此信息,我是否应该担心此过程的 ASYNC_NETWORK_IO 等待类型?它实际上对服务器性能有影响吗?
补充资料:
performance sql-server-2005 sql-server stored-procedures wait-types
如果我通过高延迟网络对 SQL Server 数据库进行一次调用,是否会由于该延迟而发生表锁定?假设我查询表 A 中的某些记录,并且 SQL Server 必须通过慢速网络返回该数据 - 当服务器通过网络发送响应时,表 A 上是否存在读取锁定,或者 SQL Server 在发送之前是否释放锁定响应?
此外,答案是否会根据响应的大小而有所不同?如果它只需要返回几 KB 与几百 MB,那会有什么不同吗?
创建显式事务、运行查询和关闭事务显然会导致表锁定,因为事务的持续时间与我的延迟相关。
sql-server ×8
backup ×1
installation ×1
join ×1
locking ×1
network ×1
null ×1
optimization ×1
performance ×1
restore ×1
security ×1
transaction ×1
wait-types ×1