我有两个表 tb1 和 tb2,tb1 上没有任何索引。我在 tb1 中填充了 1000000 行,tb2 中有 500 行,并且在 ID 列上有一个聚集索引。
为了理解嵌套循环连接,我使用了以下查询:
SELECT *
FROM tb1
INNER JOIN tb2 ON tb1.id=tb2.id
OPTION(loop join);
Run Code Online (Sandbox Code Playgroud)
我得到了以下执行计划:

没有索引的 Tb1 被扫描,成本为 2%,而索引正在 tb2 上使用,成本为 98%。

我的问题是:

有人可以向我解释执行计划以及任何指针以了解有关强制扫描的更多信息,单击运算符后按 F4 时强制索引。
在我的查询中,我比较了WHERE子句中的两个日期
一旦使用CONVERT:
CONVERT(day,InsertedOn) = CONVERT(day,GETDATE())
Run Code Online (Sandbox Code Playgroud)
另一个使用DATEDIFF:
DATEDIFF(day,InsertedOn,GETDATE()) = 0
Run Code Online (Sandbox Code Playgroud)
这是执行计划
的数据类型InsertedOn是datetime。
哪个更优化?
我在哪里可以找到查询计划可能包含在 PostgreSQL 中的可能节点类型(例如 Seq scan、groupAggregate、Nested loop ...)的详尽列表?
我有一个基于SQL Server 2005. 我在这些表上创建了索引。但是当我写一个带JOIN条件的查询时,返回的实际行数太高,而估计的行数更少。并且查询计划使用嵌套循环。[查询计划图如下。] 由于这些是新表,我认为通常的陈旧统计数据不是这里的原因。
我可以通过使用NOT EXISTS(如查询 2 中所示)重写此查询,并减少实际行数。但是我还有其他要求可以使用 LWTest 表获取详细信息INNER JOIN——大量实际行是一个问题。
那么,即使有索引和统计信息,为什么实际行数仍然如此之高,有什么线索吗?可以做些什么来降低它?
注意:TransmittedManifests 中的行数 –904。LWTest 中的行数 -- 829785
更新
注 2:Compatibility_Level 为 90。查询 1 的运行时间为 64 毫秒。查询 2 已用时间为 6 毫秒。
注 3:在这两个表上尝试了 OPTION (RECOMPILE)、重建索引和 UPDATE STATISTICS WITH FULLSCAN。但实际的行数仍然很高。
感谢 Martin Smith 提供每次执行计数(估计)和总计数(实际)差异的详细信息。实际行是所有执行的计数,估计是每次执行的计数。估计行数、实际行数和执行计数。
对于查询 1,ActualExecutionsLWTest 表的="904"。
询问
DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO
SET STATISTICS IO ON
PRINT 'BEGIN -----------------------------------------'
--Query 1
SELECT T.[Manifest]
FROM dbo.TransmittedManifests T …Run Code Online (Sandbox Code Playgroud) Management Studio 中的选项
在 Management Studio Tools->Options->Query Execution->SQL Server 上设置了一些选项,这些选项优先于在数据库级别设置的相同选项。
数据库级别的选项
在管理工作室,您右键单击一个数据库,您可以看到许多选项的默认值:(下图中的黄色部分)
使用sys.databases您可以使用 T_SQL 获取这些选项。
会话级别的选项
使用sys.dm_exec_sessions您可以掌握为当前会话设置的选项。
问题
有没有办法确保数据库设置优先于管理工作室设置?
我想过创建一个计划,并使用OPTION(使用计划), 但这会产生超出本问题范围的其他后果。
sql-server ssms execution-plan sql-server-2008-r2 configuration
我们最近从 SQL Server 2008R2 升级到 SQL Server 2014 SP1 + CU4。
几周后,执行计划出现了无法正确估计行数的问题。问题一度变得如此严重,以至于决定通过再次启用9481跟踪标志和更新统计信息来恢复到旧的基数估计器。当我说“变得如此糟糕”时,我指的是在某些情况下查询的执行时间增加了 10。
使用 traceflag 9481已经解决了问题,但这不是解决方案吗?
搜索谷歌显示,有些人采用旧的基数估计器路线,而其他人则使用2312和4199的组合来使用新的估计器。
那么在从 2008R2 升级到 2014 之后,我们应该采取什么样的跟踪标志(如果有)和其他步骤的组合?
谢谢,克雷格
4 月 26 日上午 9 点更新
4199 跟踪标志不会打开新的基数估算器。我不得不改用 2312 跟踪标志。
使用 4199 跟踪标志时,版本仍为70。Chris Wood 的回答让我想起了Brent Ozar的一篇文章,我在某个时候也读过。仍在等待查看执行时间是否有所改善。
我有下表
create table t1(
col1 varchar(255) NOT NULL,
col2 varchar(255) NULL,
col3 bigint NULL,
CONSTRAINT PK_t1 PRIMARY KEY CLUSTERED
(
col1 asc
)
)
CREATE NONCLUSTERED INDEX I_col3 ON t1(col3 desc)
Run Code Online (Sandbox Code Playgroud)
这个表有大约 10000 行,col2 总是被填充,col3 有不同百分比的非空行。
我正在运行以下查询
DECLARE @number bigint
SET @number = 123456
SELECT col1, col2 FROM t1
WHERE col3 > @number
Run Code Online (Sandbox Code Playgroud)
SQL 总是使用聚集索引扫描生成执行计划。
现在,如果我将查询作为临时查询运行,SQL 会使用键查找对 I_col3 进行索引查找
SELECT col1, col2 FROM t1
WHERE col3 > 123456
Run Code Online (Sandbox Code Playgroud)
WHERE 子句中传递的值会导致返回少量行(例如 3)
运行即席查询时,执行计划将估计行数显示为 3.32。但是,当我运行参数化查询时,它显示了 2796 行估计值。
如果我向临时查询添加索引提示,它仍会显示 2796 条估计行(不是我希望这会改变),但它确实会进行索引查找。在比较临时和参数化查询之间的逻辑读取数时,参数化查询:扫描计数 1,逻辑读取 89,物理读取 …
升级到 MySQL 5.7 后,执行 SQL 查询会填满可用存储空间。
升级是通过 AWS 控制台执行的,选择自动程序将 RDS 从 MySQL 5.6.27 升级到 MySQL 5.7.11。但是,在 mysql5.6 上流畅运行的相同查询耗尽了 mysql5.7 实例上的可用文件系统空间。
对该问题进行了研究,发现该/rdsdbdata/db/innodb/ibtmp1文件已扩展到使用所有可用存储空间。行为如图所示。
mysql5.6 和 mysql5.7 之间执行计划的额外比较显示,即使在两个数据库版本之间调整了 optimizer_switch 参数之后,5.7 包含的 2.56 亿条记录仍存在差异。
一些证据显示出与用户定义变量的使用有关,但不是决定性的。例如,SELECT 语句包括一个@count := @count + 1属性。
问题:如何缓解 MySQL 5.7 更改执行计划从而填满 RDS 实例的可用存储空间的事实。
我有以下过程,每天调用超过一百万次,我认为可以对其进行调整以更好地使用资源。
ALTER PROCEDURE [DenormV2].[udpProductTaxRateGet]
(
@itemNo varchar ( 20 ),
@calculateDate datetime,
@addressLine1 nvarchar( 50 ),
@addressLine2 nvarchar( 50 ),
@addressLine3 nvarchar( 50 ),
@addressLine4 nvarchar( 50 ),
@addressLine5 nvarchar( 50 ),
@addressLine6 nvarchar( 50 ),
@postalCode nvarchar( 20 ),
@countryCode varchar( 2 ),
@addressFormatID int
)
WITH EXECUTE AS 'webUserWithRW'
AS
--see Bocss2.dbo.[fnGetProductTax] for equivalent logic and comments in Bocss
DECLARE @Addresses TABLE (TaxRegionId int NOT NULL)
INSERT INTO @Addresses(TaxRegionId)
SELECT DISTINCT TaxRegionId
FROM dbo.[ShipTaxAddress]
WHERE [CountryCode] = @countryCode …Run Code Online (Sandbox Code Playgroud) performance sql-server-2005 sql-server execution-plan table-variable query-performance
在我的一个生产 SQL 服务器实例中,我遇到了一个问题。查询需要很长时间才能运行。在检查 SQL 查询计划时,我发现它给出了创建缺失索引的建议。我去了推荐表,发现推荐的索引已经存在于表中,但有些没有被使用。维护计划(重建索引、更新统计信息等)定期执行。我不确定为什么索引没有被使用?以及为什么查询计划在索引已经存在的情况下继续给出缺失索引的建议?任何帮助将非常感激。
performance sql-server-2008 execution-plan query-performance
execution-plan ×10
sql-server ×7
performance ×3
disk-space ×1
mysql-5.7 ×1
postgresql ×1
ssms ×1
statistics ×1
storage ×1