Questions tagged «optimization»

在数据库的上下文中,优化是指查询优化器选择有效的物理执行计划的过程。

2
如何加快选择特色?
我对某些时间序列数据有一个简单的选择: SELECT DISTINCT user_id FROM events WHERE project_id = 6 AND time > '2015-01-11 8:00:00' AND time < '2015-02-10 8:00:00'; 而且需要112秒。这是查询计划: http://explain.depesz.com/s/NTyA 我的应用程序必须执行许多不同的操作,并像这样计数。有没有更快的方法来获取此类数据?

1
什么时候可以将SARGable谓词推送到CTE或派生表中?
沙袋 在从事高质量博客文章®的工作时,我遇到了一些优化器行为,我发现这确实令人非常恼火。我没有立即作出解释,至少没有一个我满意的解释,因此我将其放在此处,以防有人出现。 如果要继续学习,可以在此处获取2013年版本的Stack Overflow数据转储。我正在使用注释表,上面还有一个索引。 CREATE INDEX [ix_ennui] ON [dbo].[Comments] ( [UserId], [Score] DESC ); 查询一 当我像这样查询表时,我得到一个奇怪的查询计划。 WITH x AS ( SELECT TOP 101 c.UserId, c.Text, c.Score FROM dbo.Comments AS c ORDER BY c.Score DESC ) SELECT * FROM x WHERE x.Score >= 500; 分数的SARGable谓词未在CTE中推送。在计划的后期,它位于过滤器运算符中。 我觉得很奇怪,因为ORDER BY和过滤器位于同一列。 查询二 如果我更改查询,它将被推送。 WITH x …

2
加入查询需要11分钟才能在300,000行表上运行
下面的查询需要花费超过11分钟的时间来执行。 SELECT `c`.*, `e`.`name` AS `employee_name`, `e`.`emp_no`, `d`.`code` AS `department_code`, IF(ew.code IS NOT NULL, ew.code, egw.code) AS shift_code, IF(ew.code IS NOT NULL, ew.time_in_from, egw.time_in_from) AS time_in_from, IF(ew.code IS NOT NULL, ew.time_out_to, egw.time_out_to) AS time_out_to, IF(ew.code IS NOT NULL, ew.next_day, egw.next_day) AS next_day FROM `tms_emp_badge_card` AS `c` LEFT JOIN `tms_door_record_raw` AS …

3
为什么我的EXISTS查询执行索引扫描而不是索引查找?
我正在优化一些查询。 对于以下查询, SET STATISTICS IO ON; DECLARE @OrderStartDate DATETIME2 = '27 feb 2016'; DECLARE @OrderEndDate DATETIME2 = '28 feb 2016'; SELECT o.strBxOrderNo , o.sintOrderStatusID , o.sintOrderChannelID , o.sintOrderTypeID , o.sdtmOrdCreated , o.sintMarketID , o.strOrderKey , o.strOfferCode , o.strCurrencyCode , o.decBCShipFullPrice , o.decBCShipFinal , o.decBCShipTax , o.decBCTotalAmount , o.decWrittenTotalAmount , o.decBCWrittenTotalAmount …

2
添加联接提示时,为什么SQL Server行估计会更改?
我有一个查询,该查询连接了几个表并且执行得很差-行估计相差1000倍,并且选择了嵌套循环连接,从而导致了多个表扫描。查询的形状非常简单,看起来像这样: SELECT t1.id FROM t1 INNER JOIN t2 ON t1.id = t2.t1_id LEFT OUTER JOIN t3 ON t2.id = t3.t2_id LEFT OUTER JOIN t4 ON t3.t4_id = t4.id WHERE t4.id = some_GUID 在处理查询时,我注意到当我提示它对一个连接使用合并连接时,它的运行速度快了很多倍。我能理解-合并联接是联接数据的更好选择,但是SQL Server选择嵌套循环时并不能正确估计它。 我不完全理解的是,为什么此联接提示会更改所有计划运营商的所有估计?通过阅读不同的文章和书籍,我假设基数估计是在构建计划之前执行的,因此使用提示不会改变估计,而是明确地告诉SQL Server使用特定的物理联接实现。 但是,我看到的是,合并提示使所有估计变得非常完美。为什么会发生这种情况,并且有任何通用的技术可以使查询优化器在没有提示的情况下做出更好的估计-考虑到统计数据显然可以做到这一点? UPD:可在此处找到匿名的执行计划:https ://www.dropbox.com/s/hchfuru35qqj89s/merge_join.sqlplan?dl =0 https://www.dropbox.com/s/38sjtv0t7vjjfdp/no_hints_join.sqlplan?dl = 0 我使用TF 3604、9292和9204检查了两个查询使用的统计信息,它们是相同的。但是,查询之间扫描/查找的索引有所不同。 除此之外,我尝试使用来运行查询OPTION (FORCE ORDER)-它的运行速度比使用合并连接还要快,为每个连接选择HASH MATCH。


2
不可搜索的持久化计算列上的索引
我有Address一个名为的表,该表具有一个称为的持久计算列Hashkey。该列是确定性的,但不精确。它具有不可搜索的唯一索引。如果运行此查询,则返回主键: SELECT @ADDRESSID= ISNULL(AddressId,0) FROM dbo.[Address] WHERE HashKey = @HashKey 我得到这个计划: 如果我强制索引,我会得到更糟糕的计划: 如果我尝试同时使用索引和查找,则会收到错误消息: 由于此查询中定义的提示,查询处理器无法生成查询计划。重新提交查询而不指定任何提示,也无需使用SET FORCEPLAN 这仅仅是因为它不精确吗?我以为如果坚持下去没关系吗? 有没有一种方法可以使该索引可查询而不将其设为非计算列? 有人在此链接到任何信息吗? 我无法发布实际的表创建,但是这是一个具有相同问题的测试表: drop TABLE [dbo].[Test] CREATE TABLE [dbo].[Test] ( [test] [VARCHAR](100) NULL, [TestGeocode] [geography] NULL, [Hashkey] AS CAST( ( hashbytes ('SHA', ( RIGHT(REPLICATE(' ', (100)) + isnull([test], ''), ( 100 )) ) + …

1
为什么在唯一索引扫描后使用聚合运算符
我有一个带有唯一索引的表,该索引针对非空值进行了过滤。在查询计划中,使用了distinct。是否有一个原因? USE tempdb CREATE TABLE T1( Id INT NOT NULL IDENTITY PRIMARY KEY ,F1 INT , F2 INT ) go CREATE UNIQUE NONCLUSTERED INDEX UK_T1 ON T1 (F1,F2) WHERE F1 IS NOT NULL AND F2 IS NOT NULL GO INSERT INTO T1(f1,F2) VALUES(1,1),(1,2),(2,1) SELECT DISTINCT F1,F2 FROM T1 WHERE F1 …

3
具有WHERE条件和GROUP BY的SQL查询的索引
我试图确定要用于带有WHERE条件的SQL查询的索引,GROUP BY而当前正在运行的索引非常慢。 我的查询: SELECT group_id FROM counter WHERE ts between timestamp '2014-03-02 00:00:00.0' and timestamp '2014-03-05 12:00:00.0' GROUP BY group_id 该表当前有32.000.000行。当我增加时间范围时,查询的执行时间会增加很多。 有问题的表如下所示: CREATE TABLE counter ( id bigserial PRIMARY KEY , ts timestamp NOT NULL , group_id bigint NOT NULL ); 我目前有以下索引,但是性能仍然很慢: CREATE INDEX ts_index ON counter USING btree (ts); …

3
优化CTE层次结构
在下面更新 我有一个具有典型acct /父帐户体系结构的帐户表来表示帐户层次结构(SQL Server 2012)。我使用CTE创建了一个VIEW,以散列层次结构,总的来说,它可以按预期的方式很好地工作。我可以在任何级别查询层次结构,并轻松查看分支。 需要根据层次结构返回一个业务逻辑字段。每个帐户记录中的一个字段描述了企业的规模(我们将其称为CustomerCount)。我需要报告的逻辑需要从整个分支汇总CustomerCount。换句话说,给定一个帐户,我需要对该帐户以及层次结构中该帐户下方每个分支中的每个子级的客户计数值进行汇总。 我使用CTE中内置的层次结构字段成功计算了该字段,该字段类似于acct4.acct3.acct2.acct1。我遇到的问题只是使其运行速度很快。如果没有这一计算字段,查询将在约3秒内运行。当我在计算字段中添加时,它变成一个4分钟的查询。 这是我能够想到的最佳版本,它可以返回正确的结果。我正在寻找有关如何在不牺牲性能的前提下重新构建此“视图”的想法。 我知道这种方法运行缓慢的原因(需要在where子句中计算谓词),但是我想不出另一种方法来构造它并仍然得到相同的结果。 这是一些示例代码,用于构建表并完全按照其在我的环境中的工作方式执行CTE。 Use Tempdb go CREATE TABLE dbo.Account ( Acctid varchar(1) NOT NULL , Name varchar(30) NULL , ParentId varchar(1) NULL , CustomerCount int NULL ); INSERT Account SELECT 'A','Best Bet',NULL,21 UNION ALL SELECT 'B','eStore','A',30 UNION ALL SELECT 'C','Big Bens','B',75 UNION ALL …

2
如何使用执行计划优化T-SQL查询
我有一个SQL查询,过去两天我一直在尝试使用试错法和执行计划进行优化,但无济于事。请原谅我这样做,但我将在此处发布整个执行计划。我已尽力使查询和执行计划中的表名和列名通用化,以简化和保护我公司的IP。可以使用SQL Sentry Plan Explorer打开执行计划。 我已经做了相当多的T-SQL,但是使用执行计划来优化查询对我来说是一个新领域,并且我确实试图理解如何做到这一点。因此,如果有人可以帮助我并解释如何解释该执行计划以在查询中找到优化它的方法,我将永远感激不已。我还有许多要优化的查询-我只需要一个跳板就可以帮助我解决第一个问题。 这是查询: DECLARE @Param0 DATETIME = '2013-07-29'; DECLARE @Param1 INT = CONVERT(INT, CONVERT(VARCHAR, @Param0, 112)) DECLARE @Param2 VARCHAR(50) = 'ABC'; DECLARE @Param3 VARCHAR(100) = 'DEF'; DECLARE @Param4 VARCHAR(50) = 'XYZ'; DECLARE @Param5 VARCHAR(100) = NULL; DECLARE @Param6 VARCHAR(50) = 'Text3'; SET NOCOUNT ON DECLARE @MyTableVar TABLE …

3
为什么OFFSET…FETCH与旧式ROW_NUMBER方案之间的执行计划有所不同?
OFFSET ... FETCHSQL Server 2012引入的新模型提供了简单,快速的分页。考虑到两种形式在语义上是相同且非常普遍的,为什么根本没有区别? 人们会假设优化器可以识别这两者,并(最大程度地)优化它们。 这是一个非常简单的情况,OFFSET ... FETCH根据成本估算,速度提高了约2倍。 SELECT * INTO #objects FROM sys.objects SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (ORDER BY object_id) r FROM #objects ) x WHERE r >= 30 AND r < (30 + 10) ORDER BY object_id SELECT * FROM #objects ORDER BY …

1
为什么聚簇索引扫描执行数如此之高?
我有两个类似的查询生成相同的查询计划,除了一个查询计划执行1316次“聚簇索引扫描”,而另一个查询计划执行1次。 这两个查询之间的唯一区别是日期标准不同。长时间运行的查询实际上会缩小日期条件,并拉回较少的数据。 我已经确定了一些对两个查询都有用的索引,但是我只想了解为什么“聚集索引扫描”运算符在查询上执行1316次实际上与执行1次查询相同。 我检查了有关正在扫描的PK的统计信息,它们是相对最新的。 原始查询: select distinct FIR_Incident.IncidentID from FIR_Incident left join ( select incident_id as exported_incident_id from postnfirssummary ) exported_incidents on exported_incidents.exported_incident_id = fir_incident.incidentid where FI_IncidentDate between '2011-06-01 00:00:00.000' and '2011-07-01 00:00:00.000' and exported_incidents.exported_incident_id is not null 生成此计划: 缩小日期范围标准后: select distinct FIR_Incident.IncidentID from FIR_Incident left join ( select incident_id …

2
“复制到tmp表”非常慢
这是我的查询示例: SELECT nickname, CASE class_id WHEN 1 THEN 'Druid' WHEN 2 THEN 'Necromancer' WHEN 3 THEN 'Mage' WHEN 4 THEN 'Priest' WHEN 5 THEN 'Warrior' WHEN 6 THEN 'Stalker' WHEN 7 THEN 'Paladin' WHEN 8 THEN 'Psionic' END class_name, ROUND(AVG(level),2) level, ROUND(AVG(tabard_id),2) tabard, CASE rank_id WHEN 1 THEN 'Leader' WHEN …

2
优化:将变量声明移至过程的顶部
在优化某些存储过程的过程中,我与DBA坐下并经历了一些阻塞和/或读/写活动频繁的存储过程。 DBA提到的一件事是我应该TABLE在存储过程的顶部声明所有变量(尤其是变量),以避免重新编译。 这是我第一次听说此消息,并且在重新访问我们拥有的所有不同存储过程之前,正在寻求一些确认。他称其为“代码的后期查看”,并且重新编译锁定了解决阻塞的架构。 将所有变量声明移到存储过程的顶部是否会减少重新编译?

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.