Questions tagged «execution-plan»

查询优化器选择的用于处理查询的策略。

1
通过删除运算符哈希匹配内部联接来提高查询性能
在尝试将以下问题的内容应用于我自己的情况时,我有点困惑,因为如果可能的话,如何摆脱运算符哈希匹配(内部联接)。 SQL Server查询性能-无需哈希匹配(内部联接) 我注意到了10%的成本,并且想知道是否可以降低它。请参阅下面的查询计划。 这项工作来自我今天必须调整的一个查询: SELECT c.AccountCode, MIN(d.CustomerSID) FROM Stage.Customer c INNER JOIN Dimensions.Customer d ON c.Email = d.Email OR ( c.HomePostCode = d.HomePostCode AND c.StrSurname = d.strSurname ) GROUP BY c.AccountCode 在添加这些索引之后: --------------------------------------------------------------------- -- Create the indexes --------------------------------------------------------------------- CREATE NONCLUSTERED INDEX IDX_Stage_Customer_HOME_SURNAME_INCL ON Stage.Customer(HomePostCode ,strSurname) INCLUDE (AccountCode) --WHERE HASEMAIL …

2
在分区少量数据时获得切合实际的查询计划
我们正在使用分区来减少由于锁定而导致的OLTP系统体验受阻的程度,该分区方案可根据客户ID将工作表分为100个分区。但是,在测试过程中,我们发现执行计划没有按照我们期望的方式选择。 该测试方案是一个具有300,000个联系记录的单个客户(每个联系人的数据被拆分为两个表),所有记录都位于一个分区中,并通过查询在该客户分区中查找500条特定的行。您可能希望像哈希匹配之类的东西会在计划的早期消除不必要的299,500,但是SQL Server似乎选择选择整个表的记录计数并将其平均分配给所有分区,然后再考虑如何它要处理的记录很多,这导致它选择了一个嵌套循环,并在此过程的后半段消除了不需要的记录。通常,此时间是针对非分区表的相同查询的9倍。 奇怪的是,在选择中添加一个选项(重新编译)给出了一个明智的计划,但是我不知为何会有所作为。这不是存储过程,在测试过程中,我们会在每次测试运行之前清除过程缓存。 当所涉及的表未分区时,即,由于估计的行数与实际的行数匹配,因此每次都选择一个适当的计划时,不会出现此行为 任何对此行为的见解将不胜感激。 模式设置: USE [Scratch] GO CREATE SCHEMA part GO CREATE PARTITION FUNCTION [ContactPartition](smallint) AS RANGE LEFT FOR VALUES (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, …

2
为什么不使用我的计划指南?
最近,我们遇到了临界点问题,由于查询优化器会忽略搜索列上的非聚集索引,因此一些过去几秒钟即可完成执行的报表查询现在要花费2分钟以上的时间。下面的示例查询: select top 100 * from [dbo].[t_Call] where ID > 0 and throwtime between '3/20/2014 7:00:00 AM' and '3/24/2014 6:59:59 AM' order by id 该ID列是聚集索引,并且Throwtime具有非聚集索引。在这种情况下,我们注意到使用了排序方式throwtime而不是ID更改查询计划和非聚集索引。我们还计划归档一些旧数据(当前有2000万行!!)。但是在应用程序中进行这些更改将需要一些时间,我需要找到一种方法使报表运行得相当快,而无需在应用程序级别进行更改(哦,这就是生命!)。 输入计划指南。我使用非聚集索引查询提示创建了以下计划指南,由于某种原因,仍然不使用非聚集索引。我想念什么吗? EXEC sp_create_plan_guide @name = N'[prod2reports_callthrowtime]', @stmt = N'select top 100 * from [dbo] . [t_Call] where ID > @0 and @1 < = ThrowTime …

1
为什么计算执行计划需要这么长时间?
我们的一位客户刚刚升级到新服务器。 对于特定的存储过程,首次执行该过程要花费三分钟以上的时间。随后的运行少于1秒。 这使我相信,最初的三分钟主要用于计算执行计划。然后,后续运行只需使用缓存的计划即可立即运行。 在我们的测试数据库上,大约需要5秒钟来计算同一步骤的计划。 我看不出计划本身有什么可怕的-尽管我不认为计划的相关性,因为计划显示了运行查询所花费的时间,而不是计算自身。 该服务器是16核,具有24 GB内存。不会发生繁重的CPU或内存负载。 是什么会导致仅在特定数据库上如此缓慢的计算? 我可以采取什么步骤找到问题的原因? 编辑 因此,我设法访问服务器并使用SET SHOWPLAN_XML ON运行查询。 我可以确认查询的CompileTime占用了查询执行时间的99%。该StatementOptmEarlyAbortReason是“超时”,我们与他们的数据库副本的原因是MemoryLimitExceeded测试数据库。

2
为什么带有参数的此递归CTE在处理文字时不使用索引?
我在树结构上使用递归CTE来列出树中特定节点的所有后代。如果我在WHERE子句中写入文字节点值,则SQL Server似乎实际上仅将CTE应用于该值,从而给出了具有较少实际行数的查询计划,等等: 但是,如果我将值作为参数传递,它似乎实现了(假脱机)CTE,然后在事实之后对其进行过滤: 我可能看错了计划。我还没有注意到性能问题,但是我担心CTE的实现会导致更大数据集的问题,尤其是在繁忙的系统中。另外,我通常会自己遍历此遍历:我遍历祖先,然后遍历到后代(以确保收集所有相关节点)。由于我的数据如何,每组“相关”节点都非常小,因此实现CTE没有任何意义。当SQL Server似乎意识到CTE时,它给我的“实际”数量带来了相当大的数目。 有没有办法让查询的参数化版本像文字版本一样工作?我想将CTE放在可重用的视图中。 用文字查询: CREATE PROCEDURE #c AS BEGIN; WITH descendants AS (SELECT t.ParentId Id ,t.Id DescendantId FROM #tree t WHERE t.ParentId IS NOT NULL UNION ALL SELECT d.Id ,t.Id DescendantId FROM descendants d JOIN #tree t ON d.DescendantId = t.ParentId) SELECT d.* FROM descendants d WHERE …

3
如何更快地获得最近行的总数?
我目前正在设计交易表。我意识到将需要计算每一行的运行总计,这可能会降低性能。因此,出于测试目的,我创建了一个包含一百万行的表。 CREATE TABLE [dbo].[Table_1]( [seq] [int] IDENTITY(1,1) NOT NULL, [value] [bigint] NOT NULL, CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED ( [seq] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO 我尝试获取10个最近的行及其运行总计,但大约花了10秒钟。 --1st attempt SELECT TOP 10 seq …


1
100%CPU的执行计划不正确
由于特定查询使用了错误的执行计划,我遇到了100%CPU峰值的严重问题。我现在花了数周时间自行解决。 我的资料库 我的样本数据库包含3个简化表。 [数据记录仪] CREATE TABLE [model].[DataLogger]( [ID] [bigint] IDENTITY(1,1) NOT NULL, [ProjectID] [bigint] NULL, CONSTRAINT [PK_DataLogger] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] [变频器] CREATE TABLE [model].[Inverter]( [ID] [bigint] IDENTITY(1,1) NOT NULL, [SerialNumber] [nvarchar](50) NOT NULL, CONSTRAINT [PK_Inverter] …

1
SQLite3不使用带有json_extract表达式的覆盖索引
我正在尝试SQLite3使用json_extract表达式在(3.18)中创建索引。我的目标是执行只需要索引即可产生结果的查询。这样做的原因是json_extract操作昂贵,在较大的数据集和/或值上进行操作时会降低性能。我得出结论,我需要一个覆盖指数来满足我的需求。 步骤1-使用标准表结构测试理论 CREATE TABLE Player ( Id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, FirstName TEXT NOT NULL, MiddleName TEXT, LastName TEXT NOT NULL ); CREATE INDEX Player_FirstName ON Player ( FirstName ASC, LastName ASC ); EXPLAIN QUERY PLAN SELECT FirstName, LastName FROM Player WHERE LENGTH(LastName) > 10 ORDER BY FirstName …

1
执行计划显示缺少索引但查询很快
在查看实际的执行计划时,即使查询所用的时间少于1秒,它也会显示缺少的索引。 SELECT Account.AccountID, Account.Name FROM account LEFT OUTER JOIN accountfeaturesetting afs ON afs.accountid = account.accountid and afs.featureid = 'Schedules' and afs.settingid = 'EditReasons' WHERE ISNULL(afs.Value, '0') = '0' AND EXISTS (SELECT 1 FROM program WHERE program.AccountID = account.AccountID AND program.Active = 1 AND (program.ScheduleEditReasonFlags <> 0 OR program.ScheduleEditReasonFields <> 0)) …

2
为什么在BIGINT col上进行此搜索具有额外的常量扫描,计算标量和嵌套循环运算符?
当我查看某些查询的实际执行计划时,我注意到WHERE子句中使用的文字常量显示为计算标量和常量扫描的嵌套链。 要重现此,我使用下表 CREATE TABLE Table1 ( [col1] [bigint] NOT NULL, [col2] [varchar](50) NULL, [col3] [char](200) NULL ) CREATE NONCLUSTERED INDEX IX_Table1 ON Table1 (col1 ASC) 其中包含一些数据: INSERT INTO Table1(col1) VALUES (1),(2),(3), (-9223372036854775808), (9223372036854775807), (2147483647),(-2147483648) 当我运行以下(废话)查询时: SELECT a.col1, a.col2 FROM Table1 a, Table1 b WHERE b.col1 > 2147483648 我看到它将在Index Seek和标量计算(根据常量)的结果中进行嵌套循环绘制。 请注意,文字大于maxint。它确实有助于写作CAST(2147483648 …

1
什么是SQLServer中的BMK运算符
我试图回答这个问题,说明from子句是可选的..但是我在计划中停留在运算符上。.下面是执行计划的屏幕截图.. 如您所见,查询计划中有BMK运算符,但没有任何指示显示其计算方式。 到目前为止,我已经尝试过的步骤: 我开始使用BMK1000进行搜索,但是它显示了使用同一运算符的一系列问题。最后,我找到了一个线程,其中显示“您要引用的BMK是保留在堆中的存储位置使用非集群索引而不是集群键。”。但是由于我没有任何索引,所以不确定与我的关系如何。 问: 什么是BMK运算符以及如何计算它。任何指针也将有帮助 这是SQLFiddle来再现问题

2
搜索谓词中的标量运算符
在SQL Server 2012中,我使用了实际查询的简化版本。从“容器”表中选择数据时,它在查找谓词中具有标量运算符。 标称运算符在此查找谓词中的用途是什么? CREATE TABLE #EligibleOrders (OrderID INT PRIMARY KEY, StatusCD CHAR(3), CreatedOnDate DATETIME ) --insert logic into #EligibleOrders --Final Query SELECT T2.OrderID ,olic.LineItemID, SUM(c.quantity) AS ShippedQty, COUNT(DISTINCT c.ContainerID) AS ShippedCases FROM #EligibleOrders T2 INNER JOIN dbo.OrderLineItemContainers (NOLOCK) AS olic ON olic.OrderID = T2.OrderID INNER JOIN dbo.Containers (NOLOCK) AS …


1
SQL Server,TOP与ROW_NUMBER
我正在学习执行计划,并尝试不同的查询并比较它们的性能,结果发现: SELECT StatisticID FROM ( SELECT StatisticID, ROW_NUMBER() OVER (ORDER BY StatisticID) AS rn FROM FTCatalog.Statistic ) AS T WHERE T.rn <= 1000 ORDER BY rn SELECT TOP 1000 StatisticID FROM FTCatalog.Statistic ORDER BY StatisticID 它们都返回相同的结果集-但是第一个执行速度更快,资源占用更少(至少SSMS告诉我),以下是执行计划: 与SQL Query Plan Explorer的比较: 谁能给我一些有关幕后实际发生情况的信息,以及为什么结果有所不同?如果您还有其他需要,请告诉我。 谢谢,伊瓦达斯。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.