小编Jer*_*oen的帖子

如何衡量或查找创建查询计划的成本?

我有一个典型的例子,参数嗅探导致一个“坏”的执行计划进入计划缓存,导致我的存储过程的后续执行非常缓慢。我可以用局部变量OPTIMIZE FOR ... UNKNOWN、 和来“解决”这个问题OPTION(RECOMPILE)。但是,我也可以深入查询并尝试优化它。

我正在尝试确定我是否应该:鉴于解决问题的时间有限,我想知道这样做的成本。在我看来,如果我坚持使用OPTION(RECOMPILE),净效果是每次运行查询时都会重新创建查询计划。所以,我想我需要知道:

如何找出创建查询计划的成本是多少?

为了回答我自己的问题,我在谷歌上搜索过(例如使用这个查询),并且我已经浏览了dm_exec_query_statsDMV列的文档 。我还检查了 SSMS 中的“实际查询计划”的输出窗口以找到此信息。最后,我搜索了 DBA.SE。这些都没有得到答案。

谁能告诉我?是否可以找到或测量创建计划所需的时间?

sql-server execution-plan

18
推荐指数
1
解决办法
4761
查看次数

某些特殊字符的 ISNUMERIC 背后的逻辑是什么?

ISNUMERIC函数有一些意外行为。MSDN 文档说:

ISNUMERIC当输入表达式计算为有效的数字数据类型时返回 1;否则返回 0。有效的数字数据类型包括:int、bigint、smallint、tinyint、decimal、numeric、money、smallmoney、float、real

它还有一个脚注:

ISNUMERIC对于某些非数字字符返回 1,例如加号 (+)、减号 (-) 和有效的货币符号,例如美元符号 ($)。有关货币符号的完整列表,请参阅money 和 smallmoney (Transact-SQL)

好的,因此+-和 列出的货币符号应被视为数字。到现在为止还挺好。

现在是奇怪的部分。首先,链接文章中的一些货币符号不是数字,包括:

  • 欧元货币符号,十六进制 20A0: ?
  • 奈拉符号,十六进制 20A6: ?
  • 里亚尔符号,十六进制 FDFC: ?

这很奇怪,我似乎无法找出原因?这个版本或环境依赖吗?

然而,事情变得更奇怪了。这里还有一些我无法解释的:

  • /不是数字,而是\啊?!
  • 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)

sql-server sql-server-2012

14
推荐指数
2
解决办法
3078
查看次数

具有层次结构的表:创建约束以防止通过外键循环

假设我们有一个对自身有外键约束的表,如下所示:

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)

在某些情况下,这种设计可能有意义(例如典型的“员工-老板-员工”关系),并且无论如何:我处于我的模式中有这种情况的情况。

不幸的是,这种设计允许数据记录中的循环,如上例所示。

那么我的问题是:

  1. 是否可以编写一个约束来检查这个?和
  2. 编写一个检查这个的约束是否可行?(如果只需要一定深度)

对于这个问题的第 (2) 部分,可能需要提及的是,我希望我的表中只有数百或在某些情况下可能有数千条记录,通常嵌套的深度不会超过大约 5 到 10 级。

附注。微软 SQL Server 2008


2012 年 3 月 14 日更新
有几个很好的答案。我现在已经接受了帮助我理解提到的可能性/可行性的那个。不过,还有其他几个很好的答案,其中一些还提供了实施建议,因此,如果您带着相同的问题来到这里,请查看所有答案;)

sql-server-2008 constraint hierarchy

10
推荐指数
3
解决办法
5228
查看次数

调用表值函数时使用 NOLOCK 提示

假设有以下函数:

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)从表值函数中进行选择。这可能吗?

sql-server sql-server-2012 functions nolock

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

在数据集查询中设置 NOLOCK 提示的选项

一些上下文:
起初我们只是“直接”编写报告,在查询中没有任何锁定提示。对于较大的报告,这有时会导致锁定问题。在第一,我们通过使用补救这WITH (NOLOCK)提示在查询表。

因为(a)它是相当突兀,和(b)很容易忘记一个表的提示,我们搬到了第二种方法设置TRANSACTION ISOLATION LEVELREAD UNCOMMITTED每个数据集的查询的顶部(这是罚款)。

正如您可能猜到的,忘记其中一个数据集的提示仍然很容易。所以这就引出了一个问题:


问题:与报告查询一起发送NOLOCK提示的选项有哪些?

附注。我意识到这在某种程度上是一个XY 问题(我对 X 有很多其他选择,例如优化查询,不报告操作数据库等),但仍然试图使其成为一个有效的问题.


选项:
以下是上面提到的选项,添加了一些我很好奇它们是否可行的选项:

  1. WITH (NOLOCK)为每个表设置提示。(突兀,很容易忘记)
  2. READ UNCOMMITTED为整个查询设置隔离级别。(还是很容易忘记)
  3. 是否可以在报告级别指定这一点?例如,确保一份报告的所有数据集查询将在不锁定的情况下运行。
  4. 是否可以在其他 SSRS 级别指定它?例如,也许为某个报告文件夹设置它,或者通过使用扩展?
  5. 是否可以在数据源/连接字符串级别指定它?例如,所有相关报告都使用某个“无锁数据源”吗?
  6. 与上一个选项相关:也许可以为特定的“no-lock-sql-user”(连接中使用的那个)指定默认锁定提示?
  7. ???

哪些选项是可行的?有没有我错过的选项?

sql-server ssrs locking

7
推荐指数
2
解决办法
2979
查看次数

重新运行特定的实际查询计划

我已经捕获了特定查询的实际查询计划。

在此之后,我更改了一些内容(包括更新统计信息)并重新运行该特定查询。现在实际的查询计划是不同的(这是有道理的)。

查询现在运行得更快了。我很好奇新的执行计划是否与此有关,因为其他更改(对 IO 设置、VM 设置、sql 实例重新启动等的更改)也可能导致性能提高。为了测试这一点,我想再次运行查询,并尝试强制 SQL Server 使用旧的执行计划。

问题:有没有办法使用用户提供的执行计划重新运行查询,甚至直接从这样的计划运行查询?

这是我试图弄清楚的:

所以底线:这可能吗?如果是这样:如何?

sql-server execution-plan sql-server-2012

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

更新报告中的数据:任何潜在的陷阱?

题:

一般而言,更新 SSRS 报告中的数据是否存在任何陷阱?*

语境:

更具体地说,我正在谈论这种情况:

  • SSRS 2008(如果需要,可以选择升级)。
  • MSSQL 2008(如果需要,可以选择升级)。
  • Web.forms ReportViewer 2010 在我们自己的 ASP.NET 应用程序中。

我只需要做一个小的数据库更新。用户可以勾选一个复选框参数“我要打印这个”,这将做一个小的更新或插入以标记报告已在特定时间点运行。该报告将仅显示上次“打印”运行以来添加的项目,因此我基于此过滤我的 WHERE 子句,仅向用户提供“新”项目。

我担心的原因是,从主要用于查看数据的工具进行更新“感觉不对”。另一方面,像上面一样小的东西似乎是最简单的解决方案。

具体问题:

以下是我正在寻求洞察力的一些具体问题:

  • 安全性:报告的连接需要与允许插入的用户一起运行,更明智的默认设置是为仅选择用户运行它?SSRS 是否有已知的类似 sql 注入的攻击?
  • 可用性:我想根据用户是否勾选复选框来进行更新。我不确定这对刷新的效果如何,以及您是否可以在执行查询时检测到渲染格式是什么(这将允许我使复选框仅在 - 例如 - PDF 导出时触发更新)。
  • 健壮性:更新语句似乎更容易出现异常(违反约束等)。不确定是否有一种优雅的方法来防止、记录、跟踪和调试这类问题。

sql-server ssrs

5
推荐指数
1
解决办法
1717
查看次数

SQL-Server: sp_spaceused gives zero rows but big dataSize for cleaned table

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-2008 sql-server disk-space

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