我正在更新我的IDENTITY溢出检查脚本以考虑DECIMAL和NUMERIC IDENTITYcolumns。
作为检查的一部分,我计算每一IDENTITY列的数据类型范围的大小;我用它来计算该范围的百分比已用完。因为DECIMAL和NUMERIC 该范围的大小2 * 10^p - 2p是精度在哪里。
我用DECIMAL和NUMERIC IDENTITY列创建了一堆测试表,并尝试按如下方式计算它们的范围:
SELECT POWER(10.0, precision)
FROM sys.columns
WHERE
is_identity = 1
AND type_is_decimal_or_numeric
;
Run Code Online (Sandbox Code Playgroud)
这引发了以下错误:
Msg 8115, Level 16, State 6, Line 1
Arithmetic overflow error converting float to data type numeric.
Run Code Online (Sandbox Code Playgroud)
我将它缩小到IDENTITY类型的列DECIMAL(38, 0)(即具有最大精度),然后我POWER()直接尝试对该值进行计算。
以下所有查询
SELECT POWER(10.0, 38.0);
SELECT CONVERT(FLOAT, (POWER(10.0, 38.0)));
SELECT CAST(POWER(10.0, 38.0) …Run Code Online (Sandbox Code Playgroud) 我想在我的数据库中通过脚本创建新函数。脚本代码如下:
IF Exists(Select * From sys.sysobjects A Where A.name =N'fn_myfunc' and xtype=N'FN') return;
CREATE FUNCTION fn_myfunc ()
returns varchar(10)
AS Begin
...
End
Run Code Online (Sandbox Code Playgroud)
但是当我执行上面的脚本时,SQL Server 返回一个错误:
'CREATE FUNCTION' must be the first statement in a query batch.
Run Code Online (Sandbox Code Playgroud) 我只是在看StackOverflow上的一篇文章,其中 Aaron Bertrand 建议使用 CTE 而不是数字表,这是执行手头任务的一种优雅方式。我的问题是,为什么 CTE 的第一行以分号开头?
;WITH n AS (SELECT TOP (10000) n FROM
(SELECT n = ROW_NUMBER() OVER
(ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2
) AS x ORDER BY n
)
SELECT n FROM n ORDER BY n; -- look ma, no gaps!
Run Code Online (Sandbox Code Playgroud)
这是为了确保 WITH 语句不会被解析为以前的内容SELECT或其他内容吗?我在 SQL Server 2005 BOL 中没有看到关于在 WITH 之前使用分号的内容。
我知道出于性能原因应该避免它,但我试图展示一个条件,它显示为演示如何确保它不会出现。
但是,我最终得到了缺少索引警告,但优化器选择不创建临时索引。
我正在使用的查询是
SELECT
z.a
FROM dbo.t5 AS z WITH(INDEX(0))
WHERE
EXISTS
(
SELECT y.a
FROM dbo.t4 AS y
WHERE y.a = z.a
)
OPTION (MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)
表模式是:
CREATE TABLE dbo.t4
(
a integer NULL,
b varchar(1000) NULL,
p varchar(100) NULL
);
CREATE TABLE dbo.t5
(
a integer NULL,
b varchar(1000) NULL
);
CREATE UNIQUE CLUSTERED INDEX c1
ON dbo.t5 (a);
Run Code Online (Sandbox Code Playgroud)
两个表都有 10,000 行,您可以使用以下方法进行模拟:
UPDATE STATISTICS dbo.t4
WITH
ROWCOUNT = 10000,
PAGECOUNT = 1000;
UPDATE STATISTICS dbo.t5
WITH
ROWCOUNT = …Run Code Online (Sandbox Code Playgroud) 我有一个 SQL 查询,我花了两天时间尝试使用试错法和执行计划进行优化,但无济于事。请原谅我这样做,但我会在这里发布整个执行计划。我已经努力使查询和执行计划中的表名和列名通用,既为了简洁又为了保护我公司的 IP。可以使用SQL Sentry Plan Explorer打开执行计划。
我已经完成了大量的 T-SQL,但是使用执行计划来优化我的查询对我来说是一个新领域,我真的试图了解如何去做。所以,如果有人能帮我解决这个问题并解释如何破译这个执行计划以在查询中找到优化它的方法,我将永远感激不尽。我还有更多的查询需要优化——我只需要一个跳板来帮助我完成第一个查询。
这是查询:
DECLARE @Param0 DATETIME = '2013-07-29';
DECLARE @Param1 INT = CONVERT(INT, CONVERT(VARCHAR, @Param0, 112))
DECLARE @Param2 VARCHAR(50) = 'ABC';
DECLARE @Param3 VARCHAR(100) = 'DEF';
DECLARE @Param4 VARCHAR(50) = 'XYZ';
DECLARE @Param5 VARCHAR(100) = NULL;
DECLARE @Param6 VARCHAR(50) = 'Text3';
SET NOCOUNT ON
DECLARE @MyTableVar TABLE
(
B_Var1_PK int,
Job_Var1 varchar(512),
Job_Var2 varchar(50)
)
INSERT INTO @MyTableVar (B_Var1_PK, Job_Var1, Job_Var2)
SELECT B_Var1_PK, Job_Var1, Job_Var2 FROM [fn_GetJobs] (@Param1, @Param2, @Param3, @Param4, …Run Code Online (Sandbox Code Playgroud) sql-server-2008 sql-server optimization t-sql execution-plan
两天前,我们的客户更改了我们的开发服务器名称之一
服务器重命名后,由于服务器名称不匹配,我所有的维护工作和其他工作都失败了。
我们使用的是sql server 2012版本和server 2008 操作系统
所以今天早上我将我的 Sql server 2012 名称重命名为更新的给定名称并制作表,程序更新
我试图在维护工作中更新本地服务器连接,但它是不可编辑的。然后我添加了新的服务器连接,但仍然没有用我在执行作业时遇到错误。
在我尝试在作业属性选项中使用目标页面后,也只选择了目标服务器并禁用了多个目标服务器。
下面的错误
以用户身份执行:NT Service\SQLSERVERAGENT。Microsoft (R) SQL Server 执行包实用程序版本 11.0.2100.60,适用于 64 位 版权所有 (C) Microsoft Corporation。版权所有。
开始时间:12:01:28 AM 错误:2013-12-16 00:01:43.98 代码:0xC00291EC 来源:{410F7661-F71A-4B68-9584-BA422AB00F02} 执行 SQL
连接任务说明:获取本地服务器连接失败. 连接可能未正确配置,或者您可能没有此连接的正确权限。结束错误
错误:2013-12-16 00:02:00.00
代码:0xC0024104
来源:Territory_Update
说明:任务上的 Execute 方法返回错误代码 0x80131904(建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误。未找到或无法访问服务器。验证实例名称是否正确,并且SQL Server 配置为允许远程连接。(提供程序:命名管道提供程序,错误:40 - 无法打开与 SQL Server 的连接))。Execute 方法必须成功,并使用“out”参数指示结果。结束错误
错误:2013-12-16 00:02:15.00
代码:0xC0024104
来源:{4E2AF328-0B8D-4905-83BE-839FDDEFC09C}
说明:任务上的 Execute 方法返回错误代码 0x80131904(建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误。找不到服务器或无法访问服务器。验证实例名称是否正确,并且SQL Server 配置为允许远程连接。(提供程序:命名管道提供程序,错误:40 - 无法打开与 SQL Server 的连接))。Execute 方法必须成功,并使用“out”参数指示结果。
结束错误 …
我有一个简单的脚本,它获取四个随机数(1 到 4),然后重新连接以获取匹配的 database_id 数。当我使用 LEFT JOIN 运行脚本时,我每次都返回四行(预期结果)。但是,当我使用 INNER JOIN 运行它时,会得到不同数量的行——有时是两行,有时是八行。
从逻辑上讲,应该没有任何区别,因为我知道 sys.databases 中存在 database_ids 1-4 的行。因为我们是从四行的随机数表中选择的(而不是加入它),所以返回的行不应该超过四行。
这在 SQL Server 2012 和 2014 中都会发生。是什么导致 INNER JOIN 返回不同数量的行?
/* Works as expected -- always four rows */
SELECT rando.RandomNumber, d.database_id
FROM
(SELECT 1 + ABS(CHECKSUM(NEWID())) % (4) AS RandomNumber
FROM sys.databases WHERE database_id <= 4) AS rando
LEFT JOIN sys.databases d ON rando.RandomNumber = d.database_id;
/* Returns a varying number of rows */
SELECT rando.RandomNumber, d.database_id
FROM
(SELECT 1 + ABS(CHECKSUM(NEWID())) …Run Code Online (Sandbox Code Playgroud) 我有一个查询,它连接了几个表并且执行得非常糟糕 - 行估计偏离了(1000 次)并且选择了嵌套循环连接,从而导致多个表扫描。查询的形状相当简单,看起来像这样:
SELECT t1.id
FROM t1
INNER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id
LEFT OUTER JOIN t4 ON t3.t4_id = t4.id
WHERE t4.id = some_GUID
Run Code Online (Sandbox Code Playgroud)
玩弄查询时,我注意到当我提示它对其中一个连接使用合并连接时,它的运行速度要快很多倍。这我可以理解 - 合并连接是连接数据的更好选择,但 SQL Server 只是没有正确选择嵌套循环。
我不完全理解的是为什么这个连接提示会改变所有计划运营商的所有估计?通过阅读不同的文章和书籍,我假设基数估计是在构建计划之前执行的,因此使用提示不会改变估计,而是明确告诉 SQL Server 使用特定的物理连接实现。
然而,我看到的是合并提示使所有估计变得非常完美。为什么会发生这种情况,是否有任何通用技术可以使查询优化器在没有提示的情况下做出更好的估计 - 考虑到统计数据显然允许这样做?
UPD:匿名执行计划可以在这里找到:https ://www.dropbox.com/s/hchfuru35qqj89s/merge_join.sqlplan?dl =0 https://www.dropbox.com/s/38sjtv0t7vjjfdp/no_hints_join.sqlplan?dl =0
我使用 TF 3604、9292 和 9204 检查了这两个查询使用的统计数据,它们是相同的。然而,被扫描/搜索的索引在查询之间是不同的。
除此之外,我尝试运行查询OPTION (FORCE ORDER)- 它比使用合并联接运行得更快,为每个联接选择 HASH MATCH。
performance sql-server optimization t-sql performance-tuning
我需要创建一些涉及层次结构的测试数据。我可以让它变得简单并做几个CROSS JOINs,但这会给我一个完全统一/没有任何变化的结构。这不仅看起来很乏味,而且测试数据缺乏变化有时会掩盖原本会发现的问题。所以,我想生成一个遵循以下规则的非统一层次结构:
WHILE循环可以很容易地做到这一点,但首选是找到一种基于集合的方法。一般而言,生成测试数据没有生产代码对效率的要求,但尝试基于集合的方法可能会更具教育意义,并有助于在未来找到基于集合的方法来解决问题。因此WHILE,不排除循环,但只有在不可能使用基于集合的方法时才能使用循环。我有一个将值存储在表变量中的存储过程。我选择这些值并在调用过程时返回它们。
我试图在另一个表变量中设置这些返回值,但我无法弄清楚。
ALTER PROCEDURE [dbo].[GetOrSetDomainId]
@DomainName varchar(50),
@DomainUrl varchar(50)
AS
BEGIN
DECLARE @DomainId bigint;
DECLARE @NumberOfRwos bigint;
DECLARE @DomainHistory TABLE
(
DomainId bigint,
HasHistory bit,
ServerOnline bit,
DatabaseOnline bit,
ServerPerformance bigint,
DatabasePerformance bigint,
SoldTickets bigint
)
SELECT @NumberOfRwos = COUNT(Id)
FROM DomainData
WHERE DomainName = @DomainName OR DomainUrl = @DomainUrl
IF(@NumberOfRwos = 0)
BEGIN
INSERT INTO DomainData (DomainName, DomainUrl) VALUES (@DomainName, @DomainUrl)
SELECT @DomainId = @@IDENTITY
INSERT INTO @DomainHistory(DomainId,HasHistory)VALUES(@DomainId, 0)
SELECT * FROM @DomainHistory
END
ELSE
BEGIN
---not important …Run Code Online (Sandbox Code Playgroud) t-sql ×10
sql-server ×8
optimization ×2
cte ×1
datatypes ×1
functions ×1
hierarchy ×1
index-spool ×1
jobs ×1
maintenance ×1
performance ×1
random ×1
syntax ×1