标签: execution-plan

查询存储计划强制失败,NO_PLAN 取决于过滤器运算符在计划中的位置

我有一个查询,我在查询存储中强制执行一个计划(该计划是为此查询编译的 SQL Server)如果我在强制执行该计划后立即运行该查询,NO_PLAN尽管数据库没有发生任何更改,但我会得到last_force_failure_reason_desc。我可以成功地对同一查询强制执行不同的计划

这个问题可以用下图来说明:

创建我们的测试数据库

USE [master]
CREATE DATABASE NO_PLAN
ALTER DATABASE [NO_PLAN] SET QUERY_STORE = ON
ALTER DATABASE [NO_PLAN] SET QUERY_STORE (OPERATION_MODE = READ_WRITE, QUERY_CAPTURE_MODE = ALL)
GO

USE NO_PLAN
GO
IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'MyTableA') DROP TABLE MyTableA
IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'MyTableB') DROP TABLE MyTableB

/* create  our tables */
CREATE TABLE [dbo].[MyTableA](
    [Column1] VARCHAR(50) NULL ,
    [Column2] VARCHAR(255) NULL ,
    [Column3] INT NULL , …
Run Code Online (Sandbox Code Playgroud)

sql-server hints execution-plan sql-server-2016 query-store

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

对于嵌套循环运算符来说,估计值似乎太低/不准确

这个问题是其他人问题的后续问题:尽管更新了统计信息和重新编译,但由于执行计划不同,添加 INNER JOIN 会破坏查询性能,为什么?

我的问题是关于执行计划的一小部分。

索引(节点 22)上的 Index Seek 运算符Events.nci_wi_...估计返回 77191 行。这是嵌套循环运算符(节点 19)的外部输入。内部输入是Locations.UC_LocationID(节点 23)上的索引查找。该节点的估计执行次数为2614。

我天真的理解是,由于嵌套循环在外部被输入 77191 行,因此它别无选择,只能执行内部运算符同样多次(至少使用内部连接逻辑运算符)。为什么这里有区别呢?

嵌套循环本身估计会返回 40 行。这比外部输入的行数少三个数量级。

我知道当 QO 需要统计估计匹配行数时这是可能的,但在这种特殊情况下,columnsEvents之间存在外键约束,并且if也存在。然后,我希望优化器假设,对于外部输入中的每一行,内部输入中恰好存在一行,嵌套循环的估计行数也应为 77191 行。为什么这里没有发生这种情况?Location(LocationId, TenantID)TenantIDLocationIDNOT NULLEvents

我也很好奇为什么在这种情况下选择嵌套循环以及为什么在排序时会发生溢出。

sql-server execution-plan cardinality-estimates

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

为什么 SQL Server 有时会估计加入空表会增加行数?

我最近遇到一个问题,tSQLt测试需要很长时间才能运行。

所测试的过程正在执行 38 个表 (!) 连接(具有 37 个伪造的表和一个表值参数)。

只有两个伪造的表和 TVP 插入了任何行

编译时间非常慢。

显示跟踪标志 8675

End of simplification, time: 0.002 net: 0.002 total: 0 net: 0.002
end exploration, tasks: 549 no total cost time: 0.013 net: 0.013 total: 0 net: 0.015
end search(0),  cost: 13372.9 tasks: 3517 time: 0.012 net: 0.012 total: 0 net: 0.028
end exploration, tasks: 3983 Cost = 13372.9 time: 0 net: 0 total: 0 net: 0.028
end search(1),  cost: 6706.79 tasks: 10187 time: 0.024 net: …
Run Code Online (Sandbox Code Playgroud)

performance sql-server execution-plan tsqlt

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

如何通过许多重复的 UNION 子查询来减少查询大小?

我使用 Postgres 13 并使用以下 DDL 定义了一个表:

CREATE TABLE item_codes (
    code    bytea                    NOT NULL,
    item_id bytea                    NOT NULL,
    time    TIMESTAMP WITH TIME ZONE NOT NULL,
    PRIMARY KEY (item_id, code)
);

CREATE INDEX ON item_codes (code, time, item_id);
Run Code Online (Sandbox Code Playgroud)

我使用以下查询:

SELECT DISTINCT time, item_id
FROM (
      (SELECT time, item_id
       FROM item_codes
       WHERE code = '\x3965623166306238383033393437613338373162313934383034366139653239'
       ORDER BY time, item_id
       LIMIT 100)
       UNION ALL
      (SELECT time, item_id
       FROM item_codes
       WHERE code = '\x3836653432356638366638636338393364373935343938303233343363373561'
       ORDER BY time, item_id
       LIMIT 100)
     ) AS items
ORDER …
Run Code Online (Sandbox Code Playgroud)

postgresql execution-plan union query-performance postgresql-performance

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

是否有选项或提示可以提高“in”子句中具有多个值的查询的性能

我们有一个表 CustomerNote,有 4 列 ID、CustomerID、Note、Date

CustomerID asc, Date desc 上有一个索引

当执行以下查询时

select top 30 
    Date 
from CustomerNote
where CustomerID in (1,5)
order by Date desc
Run Code Online (Sandbox Code Playgroud)

使用了索引,但它仍然获取 customerID 1 和 5 的所有 CustomerNote,然后排序/置顶,导致大量 CPU 使用。 在此输入图像描述

这是由于“in”子句中的多个值造成的。我知道“in”子句的值永远不会超过 10 个,因此如果 sql server 迭代 10 个,为每个 customerID 获取至少 30 个值并进行合并、排序和顶部,这将是一个更好的方法。是否有查询提示或选项可以实现此目的?

performance sql-server execution-plan execution

6
推荐指数
2
解决办法
1275
查看次数

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
查看次数

查看 SQL 2008 sp_cursorexecute 底层查询和执行计划

我性能调优Dynamics AX的应用程序,看到一个SQL跟踪长时间运行,高I / O查询的形式exec sp_cursorexecute 1073742882 ...。当我尝试运行在一个新的SQL Management Studio中的窗口,查询,我得到一个错误Could not find prepared statement with handle 1073742882.我”我不确定,但似乎缓存计划是特定于连接的。我无sp_cursorprepare迹可寻;重复用例会显示相同的准备好的句柄 ID 和新游标。由于它是我要连接的共享环境,因此我想我必须重置应用服务器并跟踪其启动才能看到它。

  • 有什么办法可以使用游标准备好的句柄ID来查看底层查询吗?
  • 有没有办法将一行dm_exec_cached_plans与这个游标相关联?
  • 有没有办法通过dm_exec_query_plan或其他方式查看执行计划?

sql-server-2008 execution-plan cursors

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

我可以做些什么来加快查询中的键查找

我正在使用 SQL2005 并针对它们调用查询 simila 对此

    declare @art table (id int primary key, naziv varchar(35) null, sifra varchar(15) null, jm int null);   

            insert into @art
            select id, left(naziv,35), left(sifra,15), jm from art a
            where   (a.id = @art_id@ or @art_id@ = 0 )

Select 
      s.art_id
     ,sum(kol) as kol
     ,sum(kol*mpc) as MPCI
     /*--and meny others --/
    from doc d 
                inner join dokumenti dk on (d.tip = dk.tip)
                inner join sdo s on (d.id=s.doc_id)
        where           
                        d.datum between  @do_datuma@ and @do_datuma@
                        and dk.prodaja = 1 …
Run Code Online (Sandbox Code Playgroud)

index sql-server-2005 sql-server execution-plan

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

执行计划使用 B+ 树索引,而且还排序

我正在使用 Oracle sqlplus。我有以下查询:

SELECT fooID from foo MINUS
SELECT fooID from bar;
Run Code Online (Sandbox Code Playgroud)

我创建了两个非聚集 B+ 树索引。一个在fooID表的字段中foo,一个在表的字段fooIDbar。之后,我分析了两个表的统计信息:foobar使用EXPLAIN PLAN .... 但我明白了:

  SELECT STATEMENT
      MINUS
        SORT UNIQUE
          INDEX FAST FULL SCAN FOO_INDEX
        SORT UNIQUE
          INDEX FAST FULL SCAN BAR_INDEX
Run Code Online (Sandbox Code Playgroud)

这怎么可能呢?做的时候INDEX FAST FULL SCAN,因为索引是 B+ 树,系统不会取回它的元组排序吗?为什么需要这样做SORT UNIQUE(数据已经排序)?

oracle-11g sqlplus execution-plan sorting explain

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

sql 可以为这个程序生成一个好的计划吗?

我读过那些本身并不总是做同样事情的过程,不会总是有一个好的计划。也就是说(如果我错了,请纠正我),如果我有一个过程,如果当天是偶数,它从表 X 中读取,否则它从表 Y 中读取,并且它第一次执行的时间是偶数,那么生成的计划将被优化对于从表 X 读取而不是从 Y 读取,即使从 Y 读取,sql 也会使用该计划,恕我直言很容易理解并尽量避免,但是作用于同一个表的过程呢。

像下面的示例(显然是一个非常简单的示例),如果它第一次运行,并且该项目确实存在,而随后的运行通常不存在(或反之亦然),我是否会得到一个“不太好”的计划这会影响性能?

CREATE PROCEDURE dbo.MyProc
(
@data    VarChar(25),
@name    VarChar(25)
)

AS

    IF NOT EXISTS (SELECT * FROM dbo.MyTable WHERE myname = @name)
    BEGIN
        INSERT dbo.MyTable (myname, mydata)
        VALUES (@name, @data)
    END
    ELSE
    BEGIN
        UPDATE dbo.MyTabel
        SET mydata = @data
        WHERE myname = @name
    END
Run Code Online (Sandbox Code Playgroud)

sql-server stored-procedures optimization execution-plan sql-server-2008-r2

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