Questions tagged «execution-plan»

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


1
为什么PostgreSQL选择较昂贵的联接顺序?
PostgreSQL使用默认值,加上 default_statistics_target=1000 random_page_cost=1.5 版 PostgreSQL 10.4 on x86_64-pc-linux-musl, compiled by gcc (Alpine 6.4.0) 6.4.0, 64-bit 我已经吸尘并进行了分析。该查询非常简单: SELECT r.price FROM account_payer ap JOIN account_contract ac ON ap.id = ac.account_payer_id JOIN account_schedule "as" ON ac.id = "as".account_contract_id JOIN schedule s ON "as".id = s.account_schedule_id JOIN rate r ON s.id = r.schedule_id WHERE …

3
为什么选择此查询的所有结果列比选择我关心的一列要快?
我有一个查询,其中使用select *不仅读取次数少得多,而且比使用占用的CPU时间少得多select c.Foo。 这是查询: select top 1000 c.ID from ATable a join BTable b on b.OrderKey = a.OrderKey and b.ClientId = a.ClientId join CTable c on c.OrderId = b.OrderId and c.ShipKey = a.ShipKey where (a.NextAnalysisDate is null or a.NextAnalysisDate < @dateCutOff) and b.IsVoided = 0 and c.ComplianceStatus in (3, 5) …

1
为什么这个LEFT JOIN的表现比LEFT JOIN LATERAL差很多?
我有以下表格(来自Sakila数据库): 电影:film_id是pkey 演员:actor_id是pkey film_actor:film_id和actor_id是影片/演员的键 我正在选择一部特定的电影。对于这部电影,我还希望所有演员都参与该电影。我对此有两个查询:一个带有a LEFT JOIN和一个带有a LEFT JOIN LATERAL。 select film.film_id, film.title, a.actors from film left join ( select film_actor.film_id, array_agg(first_name) as actors from actor inner join film_actor using(actor_id) group by film_actor.film_id ) as a on a.film_id = film.film_id where film.title = 'ACADEMY DINOSAUR' order by film.title; select film.film_id, …

1
SQL Server中执行计划创建的确定性如何?
给定以下常量: 具有相同结构(表,索引等)的相同数据库 相同的数据 相同的SQL Server和硬件配置 相同的统计 客户端中相同的SET选项 相同的SQL Server版本 相同的跟踪标志 给定这些常量,SQL Server会始终为给定查询生成相同的计划吗? 如果没有,还有其他考虑吗?是否还需要考虑不确定性因素?

2
sp_executesql何时刷新查询计划?
您必须原谅我的天真,因为我不是DBA,但我的理解是,随着时间的推移,必须重新编译数据库更改和存储过程的统计信息,以使查询计划与最新的统计信息保持最新。 假设我的数据库中有一个存储过程,可以按一定的时间间隔对最新的统计信息进行重新编译,那么将存储过程内联到代码中并将其包装在sp_executesql语句中的含义是什么?在重新编译过程的过程中,是否会丢失对查询计划的刷新? 如果在进行此更改之前我还有其他需要考虑的事项(权限除外),那么感谢您的见解。 我在MSDN上阅读过: SQL Server查询优化器将新的Transact-SQL字符串与现有执行计划进行匹配的能力受到字符串文本中参数值不断变化的影响,特别是在复杂的Transact-SQL语句中。 因此,假设我尝试进行内联和包装的存储过程sp_executesql确实包含一些参数,这是否表示尽管我的执行计划已被缓存,但使SQL Server很难找到并重用它?

1
SQL Server 2008是否存储执行计划的创建日期?
最近,我们升级了一个使用的应用程序,其中涉及修改数据库的架构。这些更改可能迫使已丢弃的缓存执行计划。如果SQL Server被迫创建许多新计划,则可能会减慢用户体验。我想看看是否是这种情况。 因此,我的问题是,SQL Server 2008是否存储缓存的执行计划的创建日期?管理视图sys.dm_exec_cached_plans没有任何日期字段,因此我怀疑没有。


1
当where子句对`value()`进行过滤时,为什么不使用二级选择索引?
设定: create table dbo.T ( ID int identity primary key, XMLDoc xml not null ); insert into dbo.T(XMLDoc) select ( select N.Number for xml path(''), type ) from ( select top(10000) row_number() over(order by (select null)) as Number from sys.columns as c1, sys.columns as c2 ) as N; 每行的样本XML: <Number>314</Number> …

1
SQL Server的优化器如何估计联接表中的行数?
我在AdventureWorks2012数据库中运行此查询: SELECT s.SalesOrderID, d.CarrierTrackingNumber, d.ProductID, d.OrderQty FROM Sales.SalesOrderHeader s JOIN Sales.SalesOrderDetail d ON s.SalesOrderID = d.SalesOrderID WHERE s.CustomerID = 11077 如果查看估算的执行计划,则会看到以下内容: 初始索引查找(右上)使用IX_SalesOrderHeader_CustomerID索引并在文字11077上进行搜索。其估计值为2.6192行。 如果使用DBCC SHOW_STATISTICS ('Sales.SalesOrderHeader', 'IX_SalesOrderHeader_CustomerID') WITH HISTOGRAM,则表明值11077在两个采样键11019和11091之间。 11019和11091之间的不同行的平均数为2.619718,或舍入为2.61972,这是为索引搜索显示的估计行的值。 我不了解的部分是针对SalesOrderDetail表的聚集索引查找的估计行数。 如果我运行DBCC SHOW_STATISTICS ('Sales.SalesOrderDetail', 'PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID'): 因此,SalesOrderID(我要加入)的密度为3.178134E-05。这意味着1 / 3.178134E-05(31465)等于SalesOrderDetail表中唯一SalesOrderID值的数量。 如果在SalesOrderDetail中有31465个唯一的SalesOrderID,则分布均匀,每个SalesOrderID的平均行数为121317(总行数)除以31465。平均值为3.85561 因此,如果要循环遍历的估计行数是2.61972,并且要返回的平均值是3.85561,则我认为估计行数将是2.61972 * 3.85561 = 10.10062。 但是估计的行数是11.4867。 我认为我对第二个估算值的理解是不正确的,不同的数字似乎表明了这一点。我想念什么?

3
为什么并行(分区流)运算符会将行估计值减少到1?
我正在使用SQL Server 2012 Enterprise。我遇到了一个SQL计划,该计划表现出一些我不完全直观的行为。在执行大量并行索引扫描操作之后,发生了并行(分区流)操作,但是该操作杀死了索引扫描(Object10.Index2)返回的行估计,从而将估计值减小为1。我已经做了一些搜索,但是还没有遇到任何可以解释这种现象的信息。查询非常简单,尽管每个表都包含数百万的记录。这是DWH加载过程的一部分,整个中间数据集都被触及过几次,但是我遇到的问题尤其与行估计有关。有人可以解释为什么并行(Repartition Strems)运算符中的精确行估计为1吗?也, 我已经发布了完整的计划以粘贴计划。 这是有问题的操作: 在添加更多上下文的情况下包括计划树: 我能否碰到Paul White提交的Connect项目的一些变体(在此处,他的博客有进一步的深入探讨)?至少这是我发现的唯一一件事,即使没有TOP运算符,它似乎也几乎接近我所遇到的问题。

2
为什么我的WHERE子句从“包含”列中受益?
根据此答案,除非在用于限制的列上建立索引,否则查询将不会从索引中受益。 我有这个定义: CREATE TABLE [dbo].[JobItems] ( [ItemId] UNIQUEIDENTIFIER NOT NULL, [ItemState] INT NOT NULL, [ItemPriority] INT NOT NULL, [CreationTime] DATETIME NULL DEFAULT GETUTCDATE(), [LastAccessTime] DATETIME NULL DEFAULT GETUTCDATE(), -- other columns ); CREATE UNIQUE CLUSTERED INDEX [JobItemsIndex] ON [dbo].[JobItems]([ItemId] ASC); GO CREATE INDEX [GetItemToProcessIndex] ON [dbo].[JobItems]([ItemState], [ItemPriority], [CreationTime]) INCLUDE (LastAccessTime); …


5
如何从Azure SQL数据库中删除错误的执行计划?
DBCC FREEPROCCACHE在Azure SQL DB中不起作用。我还能如何强制计划以一种不会损害生产系统的方式将自己从缓存中踢出(即,我不能只是随意改变表)?这是专门针对由Entity Framework创建的SQL,因此它们不是自我管理的存储过程-它实际上是动态SQL。 (来源是错误的索引->错误的统计信息,等等。这些都是固定的,但是错误的计划不会消失。) 更新: 我选择了@mrdenny的解决方案,因为他先到达了那里。但是,我已经成功使用@Aaron Bertrand的脚本执行了工作。感谢大家的帮助!

3
级联物理操作:是否保证执行顺序?
在标准SQL中,union all不能保证a的结果以任何顺序排列。因此,类似: select 'A' as c union all select 'B' 可以按任何顺序返回两行(尽管实际上,在我所知道的任何数据库上,“ A”都将排在“ B”之后)。 在SQL Server中,这变成使用“串联”物理操作的执行计划。 我很容易想到,连接操作将扫描其输入,并返回具有可用记录的任何输入。但是,我在网上(此处)找到了以下声明: 查询处理器将按照操作员出现在计划中的顺序执行该计划,第一个是最上一个,最后一个是最后一个。 问题:实际上是这样吗?这保证是真的吗? 我没有在Microsoft文档中找到任何参考,从头到尾按顺序扫描输入。另一方面,每当我尝试运行它时,结果表明实际上确实按顺序处理了输入。 有没有一种方法可以让引擎一次处理多个输入?我的测试(使用比常量更复杂的表达式)是在启用了并行的8核计算机上进行的,大多数查询的确利用了并行性。

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.