使用 SQL Server Profiler(我使用的是 SQL Server 2012),我试图生成一个有用的跟踪来显示参数值,而不仅仅是带有变量名的 SQL。存储过程遍历大量库存数据以生成一些非常有价值的结果,我正在尝试记录现有行为,以便我可以对其进行单元测试,准确定义它,然后将其重构为合理的东西。
我有一个存储过程,它在一个循环中执行一个 54 个参数的子过程,其中存储过程创建一个游标然后执行一个 while 循环。这是一个简化的视图:
CREATE PROCEDURE
[dbo].[OuterProcedure]
( @ProductCode varchar(8),
-- 41 more parameters omitted
)
AS
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NOCOUNT ON
DECLARE @AboutFourHundredLocalvariables -- omit about 400 local variable declarations.
-- OMIT ABOUT 10 temporary table declarations.
DECLARE aCursor CURSOR FAST_FORWARD FOR
SELECT [ID],bkno, -- about 40 fields omitted.
FROM vwVeryComplexViewThatDoesALotOfVeryBrutalJoins
WHERE (about_80_boolean_expressions AND omitted_here)
ORDER BY some,keys,like,this
OPEN aCursor
FETCH NEXT FROM aCursor /* Get …Run Code Online (Sandbox Code Playgroud) 我们在 AlwaysOn 组中有 2 台服务器。
虽然每个同步数据库中的用户帐户都存在于两台服务器上,但数据库实例级登录仅存在于其中一台服务器上。即 DBINSTANCE->Security->Logins 在一台服务器上丢失。
因此,当发生故障转移时,我会在第二台服务器(没有相应的实例级别登录)上登录失败。
我如何克服这个问题?我应该以特殊方式设置用户帐户吗?
根据我的分析,我们数据仓库的完整维度模型需要从 200 多个源表中提取。其中一些表将作为增量加载的一部分提取,而其他表将作为完整加载。
需要注意的是,我们有大约 225 个具有相同架构的源数据库。
据我所知,在 SSIS 中构建一个带有 OLE DB 源和 OLE DB 目标的简单数据流需要在设计时确定列和数据类型。这意味着我最终会得到 200 多个数据流,仅用于提取。
从可维护性的角度来看,这对我来说是一个大问题。如果我需要对提取代码进行某种彻底的更改,我将不得不修改 200 个不同的数据流。
另一种选择是,我编写了一个小脚本,用于读取我想从一组元数据表中提取的源数据库、表名和列。代码在多个循环中运行,并使用动态 SQL 通过链接服务器和 OPENQUERY 从源表中提取。
根据我的测试,这仍然不如使用带有 OLEDB 源和目标的 SSIS 数据流快。所以我想知道我有什么样的选择。到目前为止的想法包括:
解决这个问题的最佳方法是什么?当谈到 .NET 编程时,我是一个初学者,所以仅仅学习基础知识所需的时间也是一个问题。
我有一个存储过程 (SS2k8),其中包含一些有时为 null 或为空的表值参数。我已经看到这个StackOverflow 帖子说空/空 TVP 应该简单地从调用参数列表中省略。我的问题是我无法弄清楚如何在存储过程中检查空或空值,因为“IF (@tvp IS NULL)”在过程创建时失败,并显示消息“必须声明标量变量“@tvp””。我是否必须在 TVP 上执行 SELECT COUNT(*) 并检查零?
代码摘录:
CREATE PROCEDURE [foo] (@tvp [TvpType] READONLY) AS
IF (@tvp IS NOT NULL) -- doesn't work
BEGIN
-- lots of expensive processing
END
ELSE
BEGIN
-- a little bit of cheap processing
END
...
Run Code Online (Sandbox Code Playgroud) sql-server-2008 null sql-server t-sql table-valued-parameters
由于我是一名 DBA(并且在许多情况下,事实上的系统管理员),SQL Server 安装在我必须定期使用的几乎每台服务器上。我最近意识到我在几乎所有情况下都使用 SQL 代理作为作业调度程序,而不是本机 Windows 任务调度程序。
从我的角度来看,SQL Agent 比原生的 Windows 任务计划程序有很多优势:
但是,我无法逃避这是一种不好的做法 - SQL 代理应该只保留用于与数据库相关的任务,并且我应该让操作系统级别的任务在 Windows 任务计划程序中运行,尽管我不喜欢它的可用性。
这样依赖SQL Agent可以吗?如果没有,我是否应该考虑使用第三方 Windows 任务调度程序来获得我正在寻找的某些功能?
我有一张Employee有 100 万条记录的表。我有以下 SQL 用于在 Web 应用程序中分页数据。它工作正常。但是,我认为的一个问题是 - 派生表tblEmployee选择表中的所有记录Employee(以创建 MyRowNumber值)。
我认为,这会导致选择Employee表中的所有记录。
真的那么有效吗?或者 SQL Server 是否也被优化为只从原始Employee表中选择 5 条记录?
DECLARE @Index INT;
DECLARE @PageSize INT;
SET @Index = 3;
SET @PageSize = 5;
SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY EmpID asc) as MyRowNumber,*
FROM Employee) tblEmployee
WHERE MyRowNumber BETWEEN ( ((@Index - 1) * @PageSize )+ 1) AND @Index*@PageSize
Run Code Online (Sandbox Code Playgroud) 我今天在一个应用程序中遇到了一组存储过程,它们在长时间运行的进程中被重复调用。在每个过程中,我发现了多个不同的 select 语句,其中一些在循环中;毫不奇怪,当前使用的这些例程需要几分钟才能运行,而直觉预计它们会在几秒钟内完成。
很明显,在编写这些程序时没有考虑性能,有多个实例只是“不是一个好主意”。
导入数据时处理每一行每行需要 300 毫秒,因此相对较小的导入需要几分钟来处理。
然而,程序中涉及的表格大部分都非常小。我在想,如果所有这些表都完全驻留在内存中,那么通过重写其中的任何一个,也许不会获得那么多。
我试图确定......对于这个明显效率低下的代码,它有多大的实际影响?值得修复吗?
所以问题是:
- 有没有办法确定哪些表完全固定在内存中?
- 有没有办法打开跟踪以监视嵌套存储过程以找到特别昂贵的部分?
注意:这是在 SQL Server 2008 R2 上
我的服务器的默认排序规则是 Latin1_General_CI_AS,由以下查询确定:
SELECT SERVERPROPERTY('Collation') AS Collation;
Run Code Online (Sandbox Code Playgroud)
我惊讶地发现,通过这种排序规则,我可以使用 predicate 匹配字符串中的非数字字符LIKE '[0-9]'。
为什么在默认排序规则中会发生这种情况?我想不出这会有用的情况。我知道我可以使用二进制排序规则来解决该行为,但这似乎是实现默认排序规则的奇怪方法。
我可以通过创建一个包含所有可能的单字节字符值的列并使用数字匹配谓词过滤值来演示该行为。
以下语句创建一个包含 256 行的临时表,当前代码页中的每个代码点对应一个行:
WITH P0(_) AS (SELECT 0 UNION ALL SELECT 0),
P1(_) AS (SELECT 0 FROM P0 AS L CROSS JOIN P0 AS R),
P2(_) AS (SELECT 0 FROM P1 AS L CROSS JOIN P1 AS R),
P3(_) AS (SELECT 0 FROM P2 AS L CROSS JOIN P2 AS R),
Tally(Number) AS (
SELECT -1 + ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM P3 …Run Code Online (Sandbox Code Playgroud) 我试图更好地了解 SQL Server 的执行引擎在低内存状态下的行为。说到内存授予,我想知道是否有某种方法可以强制GrantedMemory等于RequiredMemory. (我的猜测是有一个未记录的跟踪标志可以做到这一点。有人知道它是什么吗?)
我使用的是 SQL Server 2014,情况是这样的:
CHECKSUM和RESTORE VERIFYONLY以确保可靠性),然后发送到服务器 B。bak文件,然后在那里恢复数据库。我想使用差异备份策略,以便:
完整备份仅在星期六进行,
即星期六在服务器 A 上进行完整备份 -> 运送到服务器 B -> 在服务器 B 上恢复完整备份
剩下的日子将是差异备份,
即服务器 A 上的差异备份 -> 运送到服务器 B -> 在服务器 B 上恢复差异备份
我试过了,但出现错误,说:
无法恢复日志或差异备份,因为没有文件准备好前滚。
不知道为什么。我检查sys.database_files了服务器 A 和服务器 B,我可以看到differential_Base_LSN和differential_base_GUID是相同的。任何地方/还有什么要检查的吗?
顺便说一下,在上面的第 2 步中,当我在服务器 B 上恢复差异备份时,是否每次都需要同时恢复完整备份 + 差异备份?
我只恢复了差异备份WITH RECOVERY(并收到了错误消息),因为前一天已经恢复了完整备份。
澄清一下:是的,我希望服务器 B 上的数据库在差异之间可读。我怎样才能解决这个问题?是我每晚RESTORE FULL (WITH NORECOVERY)+ …