我有一个典型的例子,参数嗅探导致一个“坏”的执行计划进入计划缓存,导致我的存储过程的后续执行非常缓慢。我可以用局部变量OPTIMIZE FOR ... UNKNOWN
、 和来“解决”这个问题OPTION(RECOMPILE)
。但是,我也可以深入查询并尝试优化它。
我正在尝试确定我是否应该:鉴于解决问题的时间有限,我想知道不这样做的成本。在我看来,如果我坚持使用OPTION(RECOMPILE)
,净效果是每次运行查询时都会重新创建查询计划。所以,我想我需要知道:
如何找出创建查询计划的成本是多少?
为了回答我自己的问题,我在谷歌上搜索过(例如使用这个查询),并且我已经浏览了dm_exec_query_stats
DMV列的文档 。我还检查了 SSMS 中的“实际查询计划”的输出窗口以找到此信息。最后,我搜索了 DBA.SE。这些都没有得到答案。
谁能告诉我?是否可以找到或测量创建计划所需的时间?
该ISNUMERIC
函数有一些意外行为。MSDN 文档说:
ISNUMERIC
当输入表达式计算为有效的数字数据类型时返回 1;否则返回 0。有效的数字数据类型包括:int、bigint、smallint、tinyint、decimal、numeric、money、smallmoney、float、real。
它还有一个脚注:
ISNUMERIC
对于某些非数字字符返回 1,例如加号 (+)、减号 (-) 和有效的货币符号,例如美元符号 ($)。有关货币符号的完整列表,请参阅money 和 smallmoney (Transact-SQL)。
好的,因此+
、-
和 列出的货币符号应被视为数字。到现在为止还挺好。
现在是奇怪的部分。首先,链接文章中的一些货币符号不是数字,包括:
?
?
?
这很奇怪,我似乎无法找出原因?这个版本或环境依赖吗?
然而,事情变得更奇怪了。这里还有一些我无法解释的:
/
不是数字,而是\
(啊?!)REPLICATE(N'9', 308)
是数字,但REPLICATE(N'9', 309)
不是第一个也是最基本的问题是:如何解释上述情况?更重要的是:背后的逻辑是什么ISNUMERIC
,所以我可以自己解释/预测所有案例?
这是重现事物的好方法:
DECLARE @tbl TABLE(txt NVARCHAR(1000));
INSERT INTO @tbl (txt)
VALUES (N''), (N' '), (N'€'), (N'$'), (N'$$'),
(NCHAR(8356)), (NCHAR(8352)), …
Run Code Online (Sandbox Code Playgroud) 假设我们有一个对自身有外键约束的表,如下所示:
CREATE TABLE Foo
(FooId BIGINT PRIMARY KEY,
ParentFooId BIGINT,
FOREIGN KEY([ParentFooId]) REFERENCES Foo ([FooId]) )
INSERT INTO Foo (FooId, ParentFooId)
VALUES (1, NULL), (2, 1), (3, 2)
UPDATE Foo SET ParentFooId = 3 WHERE FooId = 1
Run Code Online (Sandbox Code Playgroud)
该表将有以下记录:
FooId ParentFooId
----- -----------
1 3
2 1
3 2
Run Code Online (Sandbox Code Playgroud)
在某些情况下,这种设计可能有意义(例如典型的“员工-老板-员工”关系),并且无论如何:我处于我的模式中有这种情况的情况。
不幸的是,这种设计允许数据记录中的循环,如上例所示。
那么我的问题是:
对于这个问题的第 (2) 部分,可能需要提及的是,我希望我的表中只有数百或在某些情况下可能有数千条记录,通常嵌套的深度不会超过大约 5 到 10 级。
附注。微软 SQL Server 2008
2012 年 3 月 14 日更新
有几个很好的答案。我现在已经接受了帮助我理解提到的可能性/可行性的那个。不过,还有其他几个很好的答案,其中一些还提供了实施建议,因此,如果您带着相同的问题来到这里,请查看所有答案;)
假设有以下函数:
CREATE FUNCTION [dbo].[ufnTest]()
RETURNS TABLE
AS RETURN SELECT 1 AS Nr
Run Code Online (Sandbox Code Playgroud)
我的实际函数将从许多不同的表中选择实际数据。我(大部分)理解使用 nolock 提示的风险,并决定在这种情况下我真的想要它们。所以我尝试像这样调用上面的函数:
SELECT * FROM [dbo].[ufnTest]() WITH(NOLOCK)
Run Code Online (Sandbox Code Playgroud)
但是,这失败并显示以下消息:
关键字“with”附近的语法不正确。如果此语句是公共表表达式、xmlnamespaces 子句或更改跟踪上下文子句,则前一条语句必须以分号终止。
修复此错误的提示不相关。也许这个表提示不适用于表值函数?
我会考虑几种选择。一种是在我的选择查询中的所有表上使用提示,但我不想这样做,因为 (a) 每当我更改函数时我都必须记住这一点,并且 (b) 它是重复的。另一种选择是SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
,但缺点是我不太知道如何将它设置回之前的状态(并且从我的 TVF 选择之后的语句应该具有原始隔离级别)。
因此,我更愿意WITH (NOLOCK)
从表值函数中进行选择。这可能吗?
一些上下文:
起初我们只是“直接”编写报告,在查询中没有任何锁定提示。对于较大的报告,这有时会导致锁定问题。在第一,我们通过使用补救这WITH (NOLOCK)
提示在查询表。
因为(a)它是相当突兀,和(b)很容易忘记一个表的提示,我们搬到了第二种方法设置TRANSACTION ISOLATION LEVEL
到READ UNCOMMITTED
每个数据集的查询的顶部(这是罚款)。
正如您可能猜到的,忘记其中一个数据集的提示仍然很容易。所以这就引出了一个问题:
问题:与报告查询一起发送NOLOCK
提示的选项有哪些?
附注。我意识到这在某种程度上是一个XY 问题(我对 X 有很多其他选择,例如优化查询,不报告操作数据库等),但仍然试图使其成为一个有效的问题.
选项:
以下是上面提到的选项,添加了一些我很好奇它们是否可行的选项:
WITH (NOLOCK)
为每个表设置提示。(突兀,很容易忘记)READ UNCOMMITTED
为整个查询设置隔离级别。(还是很容易忘记)哪些选项是可行的?有没有我错过的选项?
我已经捕获了特定查询的实际查询计划。
在此之后,我更改了一些内容(包括更新统计信息)并重新运行该特定查询。现在实际的查询计划是不同的(这是有道理的)。
查询现在运行得更快了。我很好奇新的执行计划是否与此有关,因为其他更改(对 IO 设置、VM 设置、sql 实例重新启动等的更改)也可能导致性能提高。为了测试这一点,我想再次运行查询,并尝试强制 SQL Server 使用旧的执行计划。
问题:有没有办法使用用户提供的执行计划重新运行查询,甚至直接从这样的计划运行查询?
这是我试图弄清楚的:
所以底线:这可能吗?如果是这样:如何?
一般而言,更新 SSRS 报告中的数据是否存在任何陷阱?*
更具体地说,我正在谈论这种情况:
我只需要做一个小的数据库更新。用户可以勾选一个复选框参数“我要打印这个”,这将做一个小的更新或插入以标记报告已在特定时间点运行。该报告将仅显示自上次“打印”运行以来添加的项目,因此我基于此过滤我的 WHERE 子句,仅向用户提供“新”项目。
我担心的原因是,从主要用于查看数据的工具进行更新“感觉不对”。另一方面,像上面一样小的东西似乎是最简单的解决方案。
以下是我正在寻求洞察力的一些具体问题:
After cleaning my table with DELETE FROM MyTable
(and executing DBCC shrinkdatabase('MyDB')
should that matter) I run the statement EXEC sp_spaceused MyTable
. The results confuse me:
tableName numberOfRows reservedSize dataSize indexSize unusedSize
--------- ------------ ------------ -------- --------- ----------
MyTable 0 21664 KB 20672 KB 736 KB 256 KB
Run Code Online (Sandbox Code Playgroud)
As you can see there are zero rows, yet there's almost 21 MB of data. My question is: what are possible causes for this situation and/or how can I further investigate …
sql-server ×7
ssrs ×2
constraint ×1
disk-space ×1
functions ×1
hierarchy ×1
locking ×1
nolock ×1