在 SQL Server 中有几种假脱机。我感兴趣的两个是Table Spool s 和Index spools,在修改查询之外。
只读查询,特别是在嵌套循环连接的内侧,可以使用表或索引假脱机来潜在地减少 I/O 并提高查询性能。这些线轴可以是Eager或Lazy。就像你我一样。
我的问题是:
运行我们的企业 ERP (Dynamics AX 2012),我注意到我们的生产环境似乎比我们的开发系统慢得多。
在运行跟踪的同时在开发和生产环境中执行相同的活动后,我确认与开发相比,SQL 查询在我们的生产环境中的执行速度非常慢(平均慢 10-50 倍)。
起初我将此归因于负载,并在下班时间在生产环境上重新运行相同的活动,并在跟踪中发现相同的结果。
我清除了 SQL Server 中的等待统计信息,然后让服务器在正常生产负载下运行一段时间,然后运行以下查询:
WITH [Waits] AS
(SELECT
[wait_type],
[wait_time_ms] / 1000.0 AS [WaitS],
([wait_time_ms] - [signal_wait_time_ms]) / 1000.0 AS [ResourceS],
[signal_wait_time_ms] / 1000.0 AS [SignalS],
[waiting_tasks_count] AS [WaitCount],
100.0 * [wait_time_ms] / SUM ([wait_time_ms]) OVER() AS [Percentage],
ROW_NUMBER() OVER(ORDER BY [wait_time_ms] DESC) AS [RowNum]
FROM sys.dm_os_wait_stats
WHERE [wait_type] NOT IN (
N'CLR_SEMAPHORE', N'LAZYWRITER_SLEEP',
N'RESOURCE_QUEUE', N'SQLTRACE_BUFFER_FLUSH',
N'SLEEP_TASK', N'SLEEP_SYSTEMTASK',
N'WAITFOR', N'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
N'CHECKPOINT_QUEUE', N'REQUEST_FOR_DEADLOCK_SEARCH',
N'XE_TIMER_EVENT', N'XE_DISPATCHER_JOIN',
N'LOGMGR_QUEUE', N'FT_IFTS_SCHEDULER_IDLE_WAIT',
N'BROKER_TASK_STOP', N'CLR_MANUAL_EVENT',
N'CLR_AUTO_EVENT', N'DISPATCHER_QUEUE_SEMAPHORE', …Run Code Online (Sandbox Code Playgroud) 我有一个 SQL Server 数据库,其中的查询速度很慢,而且有很多锁定和阻塞。
当我查看缺失的索引 DMV 和查询计划时,没有任何建议。
这是为什么?
我正在接受培训,其中一个脚本具有以下命令:
SELECT SUM(Col2) FROM clust_table WHERE Col1 % 3 = 1
Run Code Online (Sandbox Code Playgroud)
我想知道这个片段在 WHERE 子句中的用途: Col1 % 3 = 1
我在互联网上做了一些研究,没有找到关于这个命令的参考。
我想知道以下两种方法之间的区别是什么:
GETUTCDATE()-2
Run Code Online (Sandbox Code Playgroud)
和
DATEADD(d,-2,GETUTCDATE())
Run Code Online (Sandbox Code Playgroud)
我想使用DATEADD是正确的方法,但想知道为什么?
更新:这绝对是一个错误。有关完整详细信息,请参阅此连接项。
在测试sp_BlitzCache 的一些更改(完全公开,我是作者之一)时,我发现了我认为是我们代码中的错误。
在某一时刻,我们匹配查询计划哈希以获得查询成本。我们这样做:
statement.value('sum(/p:StmtSimple[xs:hexBinary(substring(@QueryHash, 3)) =
xs:hexBinary(sql:column("b.QueryHash"))]/@StatementSubTreeCost)', 'float')
Run Code Online (Sandbox Code Playgroud)
就我所见,这已经奏效了。然而,在一个奇怪的情况下,XML 中的子字符串抛出一个NULL值,并且计划显示成本为 0,尽管它相当高。
深入研究执行计划(完全公开,我为托管 Paste The Plan 的公司工作),我注意到一个问题哈希的查询计划哈希长度为 17 个字符,而其余为 18 个字符。以下是示例:
QueryPlanHash="0x4410B0CA640CDA89" QueryPlanHash="0x2262FEA4CE645569" QueryPlanHash="0xED4F225CC0E97E5" -- 问题! QueryPlanHash="0xBF878EEE6DB955EA" QueryPlanHash="0x263B53BC8C14A452" QueryPlanHash="0x89F5F146CF4B476F" QueryPlanHash="0xEF47EA40805C8961" QueryPlanHash="0xB7BE27D6E43677A5" QueryPlanHash="0x815C54EC43A6A6E9"
查询计划哈希上市为BINARY 8-想必这应该是相同的长度,但到底是什么像我这样的人了解二进制值?
稍微使用 XQuery,我发现通过将子字符串更改为从第二个位置开始,它会得出一个有效(尽管不正确)的哈希值。
WITH XMLNAMESPACES('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS p)
SELECT
QueryPlanCost = statement.value('sum(/p:StmtSimple/@StatementSubTreeCost)', 'float'),
**q.n.value('substring(@QueryPlanHash, 2)', 'BINARY(8)')**
FROM #statements s
CROSS APPLY s.statement.nodes('/p:StmtSimple') AS q(n)
OPTION(RECOMPILE);
WITH XMLNAMESPACES('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS p)
SELECT
QueryPlanCost = statement.value('sum(/p:StmtSimple/@StatementSubTreeCost)', 'float'),
**q.n.value('substring(@QueryPlanHash, …Run Code Online (Sandbox Code Playgroud) 我和我的一位同事讨论了使用可序列化隔离级别的含义。他说它锁定了整个表,但我不同意告诉他它可能可以但它尝试应用范围锁并且它不应用真正的序列化,如此处所述:可序列化隔离级别。
我在文档中找不到“锁定整个表”的任何内容:SET TRANSACTION ISOLATION LEVEL。
该文档说明了一系列关于范围锁的内容,因此理论上您可以通过简单地拥有一个范围锁来锁定整个表,该范围锁可以锁定表中可能值的整个范围,但它不会锁定表。
我在这里完全错了吗?它实际上是否锁定了整个表(或多个表)?
在本演示中,我使用的是2013 版 Stack Overflow 数据库和 SQL Server 2022 CTP2,但回溯到 SQL Server 2017 也是有效的,这是我想检查的最早版本。
对于此函数,SQL Server 跟踪该函数所花费的执行时间:
CREATE OR ALTER FUNCTION
dbo.ScoreStats
(
@UserId int
)
RETURNS
@out table
(
TotalScore bigint
)
WITH SCHEMABINDING
AS
BEGIN
INSERT
@out
(
TotalScore
)
SELECT
TotalScore =
SUM(x.Score)
FROM
(
SELECT
Score =
SUM(p.Score)
FROM dbo.Posts AS p
WHERE p.OwnerUserId = @UserId
UNION ALL
SELECT
Score =
SUM(c.Score)
FROM dbo.Comments AS c
WHERE c.UserId = @UserId
) AS x; …Run Code Online (Sandbox Code Playgroud) 在这个问题上,他和我有同样的问题。我需要类似的东西:
select * from blablabla
where product
like '%rock%' or
like '%paper%' or
like '%scisor%' or
like '%car%' or
like '%pasta%'
Run Code Online (Sandbox Code Playgroud)
这是丑陋的,它没有使用索引。
据我了解,使用全文,我可以在一个字符串中选择多个单词。
您有一个接受日期时间数组的存储过程,这些数组被加载到临时表中,并用于过滤表中的日期时间列。
\n编写查询来执行过滤的最有效方法是什么?
\nUSE StackOverflow2013;\n\nCREATE TABLE\n #d\n(\n dfrom datetime,\n dto datetime,\n PRIMARY KEY (dfrom, dto)\n)\nINSERT\n #d\n(\n dfrom,\n dto\n)\nSELECT\n dfrom = \'2013-11-20\',\n dto = \'2013-12-05\'\nUNION ALL\nSELECT\n dfrom = \'2013-11-27\',\n dto = \'2013-12-12\'; \n\nCREATE INDEX\n p\nON dbo.Posts\n (CreationDate)\nWITH\n (SORT_IN_TEMPDB = ON, DATA_COMPRESSION = PAGE);\nRun Code Online (Sandbox Code Playgroud)\n我能得到的最好的就是EXISTS像这样使用:
SELECT\n c = COUNT_BIG(*)\nFROM dbo.Posts AS p\nWHERE EXISTS\n(\n SELECT\n 1/0\n FROM #d AS d\n WHERE p.CreationDate …Run Code Online (Sandbox Code Playgroud) sql-server ×10
performance ×2
t-sql ×2
datatypes ×1
functions ×1
index ×1
wait-types ×1
xml ×1