假设我们有一个像这样的表定义:
CREATE TABLE MyTab (
ID INT IDENTITY(1,1) CONSTRAINT PK_MyTab_ID PRIMARY KEY
,GroupByColumn NVARCHAR(10) NOT NULL
,WhereColumn DATETIME NULL
)
Run Code Online (Sandbox Code Playgroud)
还有一个过滤的非聚集索引,如下所示:
CREATE NONCLUSTERED INDEX IX_MyTab_GroupByColumn ON MyTab
(GroupByColumn)
WHERE (WhereColumn IS NULL)
Run Code Online (Sandbox Code Playgroud)
为什么这个索引没有“覆盖”这个查询:
SELECT
GroupByColumn
,COUNT(*)
FROM MyTab
WHERE WhereColumn IS NULL
GROUP BY GroupByColumn
Run Code Online (Sandbox Code Playgroud)
我得到这个执行计划:
KeyLookup 用于 WhereColumn IS NULL 谓词。
performance sql-server index-tuning filtered-index query-performance
我从查询存储开始,它有问题:-( 没有生成 Top Resource Consuming Queries 的报告。它只是一直说“等待”几个小时和几个小时。后台查询(请参见下面的示例)不是能够完成并消耗大量 CPU。无论我如何更改配置选项,它一直在等待和等待(甚至最后一小时报告)。这是查询存储的现实吗?听起来是一个很棒的工具,但完全是实际无法使用?
我的查询存储大小约为 1.7 GB。我正在以 1 小时的间隔和自动捕获模式收集 7 天的数据 - 所以对我来说这似乎是合理的设置。
这是一个从未完成的后台查询示例:
SELECT TOP (@results_row_count)
p.query_id query_id,
q.object_id object_id,
ISNULL(OBJECT_NAME(q.object_id),'') object_name,
qt.query_sql_text query_sql_text,
ROUND(CONVERT(float, SUM(rs.avg_duration*rs.count_executions))*0.001,2) total_duration,
SUM(rs.count_executions) count_executions,
COUNT(distinct p.plan_id) num_plans
FROM sys.query_store_runtime_stats rs
JOIN sys.query_store_plan p ON p.plan_id = rs.plan_id
JOIN sys.query_store_query q ON q.query_id = p.query_id
JOIN sys.query_store_query_text qt ON q.query_text_id = qt.query_text_id
WHERE NOT (rs.first_execution_time > @interval_end_time OR rs.last_execution_time < @interval_start_time)
GROUP BY p.query_id, qt.query_sql_text, q.object_id
HAVING COUNT(distinct p.plan_id) >= 1 …Run Code Online (Sandbox Code Playgroud) 假设我有一张桌子:
-- just for test purposes
CREATE TABLE SomeTable (
ID INT IDENTITY(1,1) NOT NULL CONSTRAINT PK__SomeTable__ID PRIMARY KEY CLUSTERED
,SomeColumn1 NVARCHAR(50) NULL
,SomeColumn2 DATETIME NULL
);
-- populate table with some rows
INSERT INTO SomeTable DEFAULT VALUES;
GO 1000
Run Code Online (Sandbox Code Playgroud)
因为第三方应用程序有一个视图将表的 ID 列从INT到NVARCHAR(假设它是必须的):
CREATE VIEW ThirdPartyView AS
SELECT
ID = CAST(ID as NVARCHAR(10))
,C1 = SomeColumn1
,C2 = SomeColumn2
FROM SomeTable;
Run Code Online (Sandbox Code Playgroud)
然后当我通过 ID 访问一行时,我得到一个 INDEX SCAN:
SELECT *
FROM ThirdPartyView
WHERE ID = N'1'
Run Code Online (Sandbox Code Playgroud)
我明白为什么。
我该怎么做才能在查询之外获得 …
performance sql-server execution-plan view type-conversion query-performance
此 SQL 代码返回“a”而不是“asdfg”:
CREATE FUNCTION [dbo].[GetPayload2] (@ID int) RETURNS VARCHAR(300) AS
BEGIN
IF @ID = 1
RETURN 'asdfg'
RETURN ''
END
GO
SELECT dbo.GetPayload2(1)
Run Code Online (Sandbox Code Playgroud)
转载于 15.0.2000.5 和 15.0.2070.41。在 SQL Server 2017 中工作正常。解决方法是使用 WITH INLINE = OFF。
编辑:如果您同意这是一个错误,请在此处投票:https : //feedback.azure.com/forums/908035-sql-server/suggestions/39190126-sql-server-2019-scalar-functions-with-inline-are -b
编辑 2:用于 MS SQL Server 2019 的 CU2 正在解决这个问题:-)
你有没有解释一下,为什么查询优化器在这个例子中选择了不同的索引和模式?
/* crete objects and data for testing */
-- table
CREATE TABLE #Test (
ID INT IDENTITY PRIMARY KEY
,CustNo INT NULL
,CustNo2 INT NULL
);
-- populate with data
WITH
L0 AS(SELECT 1 AS c UNION ALL SELECT 1),
L1 AS(SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B),
L2 AS(SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B),
L3 AS(SELECT 1 AS c FROM L2 AS A CROSS JOIN …Run Code Online (Sandbox Code Playgroud) 我在 Windows Server 2019(1809 版)上安装了 SQL Server 2019 Express Edition (CU8),并且我的所有查询都NoParallelPlansInDesktopOrExpressEdition在NoparallelPlanReason属性中进行了串行。
是不是 Express Edition 永远不会并行?我在 Microsoft 文档中找不到任何关于此的信息。
sql-server parallelism sql-server-express windows-server-2019
那些使用优秀的 sp_HumanEvents 的人,也许是作者本人,请帮助我理解我所缺少的东西(因为我的愚蠢)。
#1
当监控阻塞时,必须设置阻塞进程阈值(以秒为单位),否则blocked_process_event将不会被触发。这与 @blocking_duration_ms 参数有何关联?
示例:阻塞进程阈值 ID 设置为 10 秒 @blocking_duration_ms 保留默认 = 500 毫秒
#2
当我想在服务器重新启动时连续且独立地将结果记录到表中时,建议我使用代理作业,并使用一个示例设置一个名为sp_HumanEvents 的计划:10 秒签入 ,但在周日午夜重复运行。当SQL Server代理启动时自动启动它不是更合适吗?
我想知道是否有任何方法可以重写查询中的表达式(只是表达式,而不是整个查询)以短路 THEN 阶段的无用评估?
演示数据:
CREATE TABLE #Docs (
ID INT NOT NULL
,DocType TINYINT NOT NULL
);
CREATE TABLE #DocsItems (
IDDocs INT NOT NULL
,Amount NUMERIC(19,6)
);
INSERT INTO #Docs(ID, DocType) VALUES(1,1),(2,1),(3,2),(4,2),(5,2),(6,2);
INSERT INTO #DocsItems(IDDocs,Amount) VALUES(3,50.),(3,25.),(3,33.),(4,44.),(4,123.),(6,11.);
Run Code Online (Sandbox Code Playgroud)
主题查询:
SELECT
-- expression
SumAmount = CASE
WHEN D.DocType <> 1 THEN (SELECT SUM(Amount) FROM #DocsItems WHERE IDDocs = D.ID)
END
FROM #Docs D
WHERE D.DocType = 1 -- so CASE condition evaluates to False
Run Code Online (Sandbox Code Playgroud)
如果我将查询(故意)重写为:
SELECT
-- expression
SumAmount = CASE …Run Code Online (Sandbox Code Playgroud) 关于 SQLOS 的执行模型(RUNNING 状态、RUNNABLE 队列、WAITER 列表),当当前正在进行 RAM 中页面的逻辑读取时,任务的状态是什么?
如果是 WAITER 列表,最流行的等待类型是什么?
我可以以某种方式测量此类操作所需的时间吗?
我知道很多逻辑读取会减慢您的查询速度,很多表/索引扫描(已经位于缓冲池中)会减慢您的查询速度 - 我只想知道它们如何出现在统计信息/dmv 中或如何将其与其他数据区分开来“经典”等待类型。
我在许多服务器上观察到的 Query Store 运行时统计数据存在这种奇怪的行为,这些行为具有不同的场景,这让我不敢相信这些统计数据。还是我做错了什么?
例如,具有给定查询计划的像这样的琐碎查询:
Stats ( sys.query_store_runtime_stats)max_logical_io_reads在某个偶然的时间间隔报告绝对疯狂的数字:
但是 table 总共只分配了 27 页!
我正在通过跨许多环境的不同查询遇到这种现象。它正在破坏我的回归查询分析。
具有不同读取次数的查询没有不同的计划。
堆表只显示很少更新和插入。巧合的是,我以堆为例。我在使用集群表时也遇到过这种情况。
sql-server ×8
performance ×5
query-store ×2
t-sql ×2
index-tuning ×1
monitoring ×1
optimization ×1
parallelism ×1
view ×1
waits ×1