标签: execution-plan

执行计划不显示内存授予

我在 Azure (DS11) 上的 VM 上安装了 SQL Server 2019。我试图在这里使用这篇文章来说明自适应查询处理。问题是,当我 CTRL+L在 SQL Server Management Studio 中查看执行计划时,我看不到那里的内存授予。

我现在的问题是,如果我以管理员身份登录,是否只能看到内存授予?还是 SQL Server 2019 的查询引擎与 SQL Server 2017 完全不同?

sql-server ssms execution-plan sql-server-2019 memory-grant

6
推荐指数
1
解决办法
655
查看次数

为什么第一个执行计划不使用 RowCount Spool?

这是我在SQL Server 2008 R2, 2012,上测试过的复制品2016

第二个和第三个查询确实使用了RowCount Spool,为什么第一个没有?

create table dbo.t (id int identity primary key, v int);
--create statistics ST_t__v on dbo.t(v) with norecompute;

insert into dbo.t (v)
select top (10000) rand(checksum(newid())) * 5
from master.dbo.spt_values a cross join
     master.dbo.spt_values b;
go

declare @v int;

set statistics xml, io on;
select @v = v from dbo.t where exists(select 1 from dbo.t where v = 4);
select @v = v from dbo.t where exists(select …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization execution-plan

6
推荐指数
1
解决办法
207
查看次数

QueryStore 计划强制限制

我有一个DELETE针对带有全文索引列的表运行的语句,cascade启用了一些外键。它看起来像这样:

DELETE FROM dbo.STUDENTS WHERE STUDENTID=@STUDENTID
Run Code Online (Sandbox Code Playgroud)

有时会编译一个计划,其中包括对所有索引操作的非常高的行估计,因此DELETE需要很长时间并导致锁定。

我试图迫使QueryStore一个很好的计划,但是这并不实际工作,表现出last forced plan failure descriptionNO_PLAN

我已确保没有可能使计划无效的架构更改。

查看执行计划,我看到这DELETE涉及到一个包含 FT 索引的系统表的连接:

在此处输入图片说明

加入 FT 索引是否意味着不支持计划强制?

sql-server full-text-search execution-plan sql-server-2016 query-store

6
推荐指数
1
解决办法
291
查看次数

为什么在这个例子中我们有 Top N Sort?

在下面的例子中,结果Index Spool已经排序,为什么我们Top N Sort这里有而不是简单的Top

use tempdb;
go

create table dbo.t1 (id int identity primary key, v int);
create table dbo.t2 (id int identity primary key, v int);

insert into dbo.t1
(v)
select top (1000)
row_number() over (order by 1/0)
from
master.dbo.spt_values a cross join
master.dbo.spt_values b;

insert into dbo.t2
(v)
select top (10000)
row_number() over (order by 1/0) + 10000
from
master.dbo.spt_values a cross join
master.dbo.spt_values b;

set statistics xml, io on;

select
sum(a.v …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization execution-plan

6
推荐指数
1
解决办法
120
查看次数

为什么 ORDER BY NULLS LAST 会影响主键上的查询计划?

使用 PostgreSQL 11,我有下表,大约有 4.5 亿行:

postgres=> \d+ sales
                                                             Table "public.sales"
              Column               |            Type             |             Modifiers              | Storage  | Stats target | Description
-----------------------------------+-----------------------------+------------------------------------+----------+--------------+-------------
 created_terminal_id               | integer                     | not null                           | plain    |              |
 company_id                        | integer                     | not null                           | plain    |              |
 customer_id                       | integer                     |                                    | plain    |              |
 sale_no                           | character varying(20)       | not null                           | extended |              |
 sale_type                         | smallint                    | not null                           | plain    |              |
 source_type                       | smallint                    | not null                           | plain …
Run Code Online (Sandbox Code Playgroud)

postgresql index null order-by execution-plan

6
推荐指数
1
解决办法
442
查看次数

禁用特定视图的顶部 (n) 排序优化

我有一个具有复杂逻辑和三个深度级别(嵌套视图)的视图。由于复杂,我无法粘贴执行计划。

由于视图的目的是向数据分析师提供一些业务分析,而他们正在开发报告时,他们会通过执行选择(前 N 个)查询来检查视图样本。

视图中的这个(前 N 个)查询执行得非常糟糕,因为优化器正在为此视图选择不同的执行计划(afaik CQScanTopSortNew

我尝试对顶部 (N) 用例进行一些优化,例如使用哈希连接,但这会破坏非顶部 (n) 用例。

非顶级 (n) 表现良好。我想知道如何防止优化器在具有 top (n) 子句时选择不同的执行计划,而不会显着改变视图的结构或功能。

例如,如果我在视图中添加一个 select distinct ,优化器总是会选择正确的计划,但视图的功能会发生变化。

sql-server execution-plan sql-server-2016 performance-tuning

6
推荐指数
1
解决办法
299
查看次数

为 WHERE 和 ORDER BY 创建多列索引

我正在尝试创建一个同时在 WHERE 和 ORDER BY 子句中使用的索引。阅读 Postgres 14 文档(11.4.索引和 ORDER BY - https://www.postgresql.org/docs/14/indexes-ordering.html)让我相信:

除了简单地查找查询要返回的行之外,索引还可以按特定的排序顺序传递它们。这允许遵守查询的 ORDER BY 规范,而无需单独的排序步骤。

哇,听起来棒极了,我们来试试吧!我创建了一个测试表,一个包含 WHERE 和 ORDER BY 列的索引,并用数据填充它:

DROP TABLE IF EXISTS testdata;
CREATE TABLE testdata
(
    question_id   TEXT        NOT NULL UNIQUE PRIMARY KEY,
    answerer_id   TEXT        NOT NULL,
    question_date TIMESTAMPTZ NOT NULL,
    answer_date   TIMESTAMPTZ NOT NULL
);

DROP INDEX IF EXISTS idx1;
CREATE INDEX idx1 ON testdata (answerer_id, answer_date, question_date);

TRUNCATE testdata;
INSERT INTO testdata(question_id, answerer_id, question_date, answer_date)
SELECT CONCAT('question_', LPAD(i::TEXT, 4, '0')),
       CONCAT('answerer_', …
Run Code Online (Sandbox Code Playgroud)

postgresql index execution-plan

6
推荐指数
1
解决办法
1225
查看次数

如何通过子查询或连接来利用分区修剪?

我有一个分区表...

CREATE TABLE erco.rtprices
(
    scedtime timestamp with time zone NOT NULL,
    node_id integer NOT NULL,
    lmp numeric(12,6),
    CONSTRAINT rtprices_pkey PRIMARY KEY (scedtime, node_id)
) PARTITION BY LIST (node_id);
Run Code Online (Sandbox Code Playgroud)

每个都有node_id自己的分区。

如果我进行直接查询(第一个版本),例如:

explain select scedtime, lmp 
from erco.rtprices
where node_id = 11111
Run Code Online (Sandbox Code Playgroud)

然后该计划仅对rtprices_11111分区进行顺序扫描。 这就是我要的。

但是,如果我执行(第二个版本)查询,例如

explain select scedtime, lmp 
from erco.rtprices
inner join erco.nodes using (node_id)
where nodename = 'somename'
Run Code Online (Sandbox Code Playgroud)

那么该计划包括对每个分区进行顺序扫描,即使此查询与第一个查询一样有限制。

我尝试了上述查询的另一种形式(第三个版本)。

explain select scedtime, lmp 
from erco.rtprices
where node_id = (select node_id from erco.nodes where nodename='somename') …
Run Code Online (Sandbox Code Playgroud)

postgresql execution-plan partitioning postgresql-performance postgresql-13

6
推荐指数
1
解决办法
1714
查看次数

执行计划中的位图创建导致聚集索引扫描的错误估计

给定 StackOverflow2010 数据库上的以下简单查询:

SELECT  u.DisplayName,
        u.Reputation
FROM    Users u
        JOIN Posts p
            ON u.id = p.OwnerUserId
WHERE   u.DisplayName = 'alex' AND
        p.CreationDate >= '2010-01-01' AND
        p.CreationDate <= '2010-03-01'
Run Code Online (Sandbox Code Playgroud)

我试图理解为什么创建索引

CREATE INDEX IX_CreationDate ON Posts
(
    CreationDate
)
INCLUDE (OwnerUserId)
Run Code Online (Sandbox Code Playgroud)

产生更好的估计Posts.CreationDate

当我运行没有索引的查询时,我得到Plan 1。在此计划中,SQL Server 估计 Posts 上的 CI 扫描产生 298,910 行,实际上返回 552 行 - 这个估计值相差甚远。

添加索引后,我会得到Plan 2,这会导致索引查找和更准确的估计。

我很好奇为什么添加索引会导致更好的估计,因为当在谓词中使用列时会创建统计信息WHERE,无论它是否被索引。

经过进一步检查,我可以看到计划 1 与计划 2 上的谓词Posts.CreationDate不同:

计划 1 谓词

[StackOverflow2010].[dbo].[Posts].[CreationDate] as [p].[CreationDate]>='2010-01-01 00:00:00.000' AND [StackOverflow2010].[dbo].[Posts].[CreationDate] …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan database-internals cardinality-estimates sql-server-2019

6
推荐指数
1
解决办法
2317
查看次数

SQL Server 如何优化 Hierarchyid::IsDescendantOf() 上的 JOIN?

我有具有树结构的表(由hierarchyid列定义),我想选择特定记录的所有后代。为此,我正在使用hiearchyid.IsDescendantOf()方法。

我预计,由于我不进行简单的比较,但我正在执行操作(在本例中我调用该IsDescendantOf()方法),那么我将得到一些带有索引扫描等的可怕执行计划。

然而,SQL Server 将其优化为漂亮的小索引查找。

执行计划

我很困惑为什么以及如何。

CLR 类型上的调用方法通常会被优化吗?我假设 SQL Server 将 CLR 类型视为不透明的黑匣子,因此无法发挥其魔力。(因为它也无法在本机 SQL 函数上执行此操作。)

或者这仅适用于该特定方法?(由于这些hieararchyid值是按深度优先排序的,因此我只需通过比较就可以获得类似的结果。

演示:

CREATE TABLE dbo.HierarchyExample (
    Id INT PRIMARY KEY,
    Hieararchy HIERARCHYID NOT NULL
);

INSERT INTO dbo.HierarchyExample(Id, Hieararchy)
VALUES
(1,  hierarchyid::Parse('/1/')),
(2,  hierarchyid::Parse('/1/1/')),
(3,  hierarchyid::Parse('/1/2/')),
(4,  hierarchyid::Parse('/1/3/')),
(5,  hierarchyid::Parse('/1/3/1/')),
(6,  hierarchyid::Parse('/1/3/2/')),
(7,  hierarchyid::Parse('/1/3/3/')),
(8,  hierarchyid::Parse('/1/4/')),
(9,  hierarchyid::Parse('/1/4/1/')),
(10, hierarchyid::Parse('/1/4/2/'));

CREATE INDEX IX_HierarchyExample_Hierarchy 
ON dbo.HierarchyExample (Hieararchy);

SELECT descendant.*
FROM HierarchyExample ancestor
    INNER JOIN HierarchyExample descendant
        ON …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan sql-server-2019

6
推荐指数
1
解决办法
407
查看次数