Questions tagged «optimization»

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

2
未找到足够好的计划的查询
我有一个SQL Server 2012数据库。我注意到Reason for early termination of statement optimization某些查询的价值,而所有查询都给出Good Enough Plan Found。现在我的问题是: 什么是“提早终止语句优化的原因”的所有可能类型。我确实在msdn中进行了搜索,但没有完整的值列表。 是否有DMV或扩展事件列出了由于找到了“足够好的计划”以外的原因而终止优化的所有查询?我引用了以下两篇文章,其中未列出所有可能性。[此外,它们在我的数据库中给了我不同的结果]。 查找:查询编译超时 识别不够好的查询计划

3
强制流量不同
我有一张这样的桌子: CREATE TABLE Updates ( UpdateId INT NOT NULL IDENTITY(1,1) PRIMARY KEY, ObjectId INT NOT NULL ) 本质上跟踪ID不断增加的对象的更新。 该表的使用者将选择一个由100个不同的对象ID组成的块,这些ID UpdateId由一个特定的并从其开始UpdateId。从本质上讲,跟踪它停止的位置,然后查询任何更新。 我发现这是一个有趣的优化问题,因为我只能通过编写恰好由于索引而做我想要做的查询的查询来生成一个最大最优查询计划,但不能保证我想要的: SELECT DISTINCT TOP 100 ObjectId FROM Updates WHERE UpdateId > @fromUpdateId @fromUpdateId存储过程参数在哪里。 有以下计划: SELECT <- TOP <- Hash match (flow distinct, 100 rows touched) <- Index seek 由于UpdateId正在使用对索引的查找,因此结果已经不错,并且可以按照我想要的那样从最低更新ID到最高更新ID进行排序。这会生成一个流程明确的计划,这正是我想要的。但是排序显然不能保证行为,所以我不想使用它。 此技巧还导致了相同的查询计划(尽管具有冗余的TOP): …

3
跟踪标志4199-全局启用?
这可能属于观点类别,但我很好奇是否人们使用跟踪标志4199作为SQL Server的启动参数。对于那些使用过它的人,您在什么情况下遇到查询回归? 当然,这似乎似乎是潜在的整体性能优势,我正在考虑在我们的非生产环境中在全球范围内启用它,并将其放置几个月以找出任何问题。 2014年(或2016年)默认情况下是否将4199中的修补程序纳入优化程序?尽管我理解不引入计划外更改的情况,但将所有这些修复隐藏在版本之间似乎很奇怪。 我们使用的是2008、2008R2,大部分使用的是2012。

2
如果查询在逻辑上相似,为什么计划会有所不同?
我编写了两个函数来回答《七周》中“七个数据库”中第3天的第一个作业问题。 创建一个存储过程,您可以在其中输入自己喜欢的电影标题或演员的名字,它将根据演员出演的电影或类似类型的电影返回前五个建议。 我的第一次尝试是正确的但很慢。返回结果最多可能需要2000毫秒。 CREATE OR REPLACE FUNCTION suggest_movies(IN query text, IN result_limit integer DEFAULT 5) RETURNS TABLE(movie_id integer, title text) AS $BODY$ WITH suggestions AS ( SELECT actors.name AS entity_term, movies.movie_id AS suggestion_id, movies.title AS suggestion_title, 1 AS rank FROM actors INNER JOIN movies_actors ON (actors.actor_id = movies_actors.actor_id) INNER JOIN …

3
通常“ WHERE 1 = 1”会影响查询性能吗?
我最近看到了一个问题“ where 1 = 1 statement”;我在构造动态SQL时经常使用的SQL构造,目的是编写更简洁的代码(从宿主语言的角度来看)。 一般来说,对SQL语句的这种添加是否会对查询性能产生负面影响?我不是在寻找有关特定数据库系统的答案(因为我已经在DB2,SQL Server,MS-Access和mysql中使用了它),除非没有具体说明就不可能回答。

2
如何在postgres中对现有表进行分区?
我想按日期范围对具有1M +行的表进行分区。通常如何做到这一点而又不需要太多的停机时间或冒着丢失数据的风险?这是我正在考虑的策略,但可以提出一些建议: 现有表是主表,子表继承自该表。随着时间的流逝,数据会从主数据移到子数据,但是一段时间后,某些数据将在主表中,而某些数据将在子表中。 创建一个新的主表和子表。在子表的现有表中创建数据副本(因此数据将驻留在两个位置)。子表拥有最新数据后,请更改所有插入以指向新的主表并删除现有表。

7
在SQL Server中优化数值范围(间隔)搜索
此问题类似于优化IP范围搜索?但是那只限于SQL Server 2000。 假设我将1000万个范围临时存储在一个表中,该表的结构和填充如下。 CREATE TABLE MyTable ( Id INT IDENTITY PRIMARY KEY, RangeFrom INT NOT NULL, RangeTo INT NOT NULL, CHECK (RangeTo > RangeFrom), INDEX IX1 (RangeFrom,RangeTo), INDEX IX2 (RangeTo,RangeFrom) ); WITH RandomNumbers AS (SELECT TOP 10000000 ABS(CRYPT_GEN_RANDOM(4)%100000000) AS Num FROM sys.all_objects o1, sys.all_objects o2, sys.all_objects o3, sys.all_objects o4) …

2
当临时表使用查找和书签查找时,为什么表变量强制索引扫描?
我试图理解为什么使用表变量会阻止优化器使用索引查找,然后使用书签查找和索引扫描。 填充表格: CREATE TABLE dbo.Test ( RowKey INT NOT NULL PRIMARY KEY, SecondColumn CHAR(1) NOT NULL DEFAULT 'x', ForeignKey INT NOT NULL ) INSERT dbo.Test ( RowKey, ForeignKey ) SELECT TOP 1000000 ROW_NUMBER() OVER (ORDER BY (SELECT 0)), ABS(CHECKSUM(NEWID()) % 10) FROM sys.all_objects s1 CROSS JOIN sys.all_objects s2 CREATE INDEX …

1
EXPLAIN ANALYZE不显示plpgsql函数内部查询的详细信息
我在PostgreSQL 9.3中使用PL / pgSQL函数,内部有几个复杂的查询: create function f1() returns integer as $$ declare event tablename%ROWTYPE; .... .... begin FOR event IN SELECT * FROM tablename WHERE condition LOOP EXECUTE 'SELECT f2(event.columnname)' INTO dummy_return; END LOOP; ... INSERT INTO ... FROM a LEFT JOIN b ... LEFT JOIN c WHERE ... UPDATE …

3
将具有多个联接的SQL查询拆分为较小的联接有帮助吗?
我们需要每晚在SQL Server 2008 R2上进行一些报告。计算报告需要几个小时。为了缩短时间,我们预先计算了一张桌子。该表是基于JOINining 12个很大的表(数十亿行)创建的。 直到几天前cca才花费了4个小时来计算此聚合表。我们的DBA将此大联接分成3个较小的联接(每个联接4个表)。每次都将临时结果保存到一个临时表中,该表将在下一个联接中使用。 DBA增强的结果是,聚合表是在15分钟内计算出来的。我想知道这怎么可能。DBA告诉我,这是因为服务器必须处理的数据数量较少。换句话说,在大型原始联接中,与汇总较小的联接相比,服务器必须处理更多的数据。但是,我认为优化器将通过原始的大联接有效地完成此任务,自行拆分联接并仅发送下一个联接所需的列数。 他所做的另一件事是他在一个临时表上创建了一个索引。但是,我再一次认为优化器将在需要时创建适当的哈希表,从而更好地优化计算。 我曾与我们的DBA讨论过此事,但他本人不确定是什么原因导致了处理时间的缩短。他只是提到,他不会怪服务器,因为计算如此大的数据可能不堪重负,而且优化器可能很难预测最佳的执行计划...。我了解这一点,但是我想对原因进行更多定义。 因此,问题是: 有什么可能导致重大改进? 将大联接拆分为较小联接是标准程序吗? 如果有多个较小的联接,则服务器必须处理的数据量真的减少了吗? 这是原始查询: Insert Into FinalResult_Base SELECT TC.TestCampaignContainerId, TC.CategoryId As TestCampaignCategoryId, TC.Grade, TC.TestCampaignId, T.TestSetId ,TL.TestId ,TSK.CategoryId ,TT.[TestletId] ,TL.SectionNo ,TL.Difficulty ,TestletName = Char(65+TL.SectionNo) + CONVERT(varchar(4),6 - TL.Difficulty) ,TQ.[QuestionId] ,TS.StudentId ,TS.ClassId ,RA.SubjectId ,TQ.[QuestionPoints] ,GoodAnswer = Case When TQ.[QuestionPoints] Is null Then …

2
是否可以给优化器更多或所有需要的时间?
鉴于优化器无法花所有需要的时间(它必须使执行时间最小化并且不做任何贡献)来探索所有可能的执行计划,因此有时它会被切断。 我想知道是否可以覆盖它,以便您可以在需要的所有时间(或一定的毫秒数)内给予优化器。 我不需要这个(atm),但是我可以想象这样一个场景:在一个紧密的循环中执行一个复杂的查询,而您想提出一个最佳计划并事先对其进行缓存。 当然,它存在一个死循环,您应该重写查询,以便它消失但请耐心等待。 出于好奇,这更多是一个问题,还需要了解短路优化和完整优化之间有时是否存在区别。 事实证明,您可以使用跟踪标志2301给优化器更多时间。这并不是我所要的,但它接近了。 我发现的最佳信息是Ian Jose 在SQL Server 2005 SP1中的查询处理器建模扩展中。 请谨慎使用此跟踪标志!但是在提出更好的计划时可能会很有用。也可以看看: 由Grant Fritchey 标记为“优化级别”的文章。 在升级到SQL Server 2008之前……由Brent Ozar撰写。 Microsoft支持在高性能工作负载中运行时的SQL Server调整选项。 我在考虑具有大量联接的查询,其中联接顺序的解决方案空间呈指数爆炸式增长。SQL Server使用的试探法非常好,但是我想知道优化器是否有更多时间(在几秒钟甚至几分钟的范围内)是否会提出不同的顺序。

3
MySQL InnoDB page_cleaner设置可能不是最佳的
在mysqld.log中看到此注释: [Note] InnoDB: page_cleaner: 1000ms intended loop took 15888ms. The settings might not be optimal. (flushed=200 and evicted=0, during the time.) 似乎在这里提到了这样的事情: MySQL实例停滞“正在执行SYNC索引” 我的问题是:如果在日志中看到此注释,应该采取什么措施(如果有)? MySQL和OS版本: mysql-community-server- 5.7.9 -1.el7.x86_64 centos-release-7-1.1503.el7.centos.2.8.x86_64 运行显示变量,例如“ innodb%”;如建议显示: innodb_page_cleaners | 1

1
PostgreSQL的GEQO(遗传查询优化)的修改
我需要实现与PostgreSQL的GEQO功能一致的功能。我知道GEQO方法是将查询计划编码为整数字符串,并且GEQO随机生成这些可能的连接序列。来源:http : //www.postgresql.org/docs/9.3/static/geqo-pg-intro.html 我的问题是:如果我明确知道正确的连接顺序,那么如何修改GEQO函数,这样我就不必搜索其他连接顺序。例如,如果我知道加入4个关系的最佳方法是4-1-3-2,则不必检查其他排列。 关于如何在PostgreSQL中实现GEQO的资料不多。PostgreSQL仅给出了GEQO功能的整体视图,而没有太多解释。 还是可以不使用GEQO在standard_join_search()本身中实现此功能?

3
Oracle没有为长键使用唯一索引
我的测试数据库中有一个包含25万行的表。(有几亿个产品正在生产,我们在那里也可以观察到相同的问题。)该表具有nvarchar2(50)字符串标识符(不是null),并且具有唯一索引(不是PK)。 标识符由第一部分组成,该部分在我的测试数据库中具有8个不同的值(在生产中大约有1000个),然后是@符号,最后是一个1到6位数字的数字。例如,可能有5万行以“ ABCD_BGX1741F_2006_13_20110808.xml @”开头,然后是5万个不同的数字。 当我根据其标识符查询单行时,基数估计为1,成本非常低,可以正常工作。当我在一个IN表达式或一个OR表达式中查询带有多个标识符的多行时,索引的估计是完全错误的,因此使用了全表扫描。如果我用一个索引强加索引,它会非常快,实际上全表扫描的执行速度要慢一个数量级(并且生产速度要慢得多)。因此,这是一个优化程序问题。 作为测试,我使用完全相同的DDL和完全相同的内容复制了该表(在相同的模式+表空间中)。我在第一个表上重新创建了唯一索引以取得良好效果,并在克隆表上创建了完全相同的索引。我做了一个DBMS_STATS.GATHER_SCHEMA_STATS('schemaname',estimate_percent=>100,cascade=>true);。您甚至可以看到索引名称是连续的。因此,现在两个表之间的唯一区别是,第一个表是在很长一段时间内以随机顺序加载的,块分散在磁盘上(与其他几个大表一起放在一个表空间中),第二个表是成批加载的插入选择。除此之外,我无法想象任何区别。(自上次大删除以来,原始表已缩小,此后没有一个删除。) 这是病假表和克隆表的查询计划(黑色笔刷下的字符串在图片中相同,灰色笔刷下的字符串也一样): (在此示例中,有1867行以黑色刷过的标识符开头。2行查询产生的基数为1867 * 2,3行查询产生的基数为1867 * 3,依此类推。巧合的是,Oracle似乎并不在乎标识符的结尾。) 什么可能导致此行为?显然,在生产中重新创建表将非常昂贵。 USER_TABLES:http : //i.stack.imgur.com/nDWze.jpg USER_INDEXES:http : //i.stack.imgur.com/DG9um.jpg 我只更改了架构和表空间名称。您可以看到表名和索引名与查询计划屏幕快照上的相同。

1
使用RECOMPILE查询提示时查询之间执行时间的巨大差异
我在同一SQL Server 2005实例上运行两个几乎相同的查询: 第一个是SELECTLINQ生成的原始查询(我知道,我知道...我不是应用程序开发人员,只是DBA :)。 第二个与第一个完全相同,最后添加一个OPTION (RECOMPILE)。 没有其他改变。 第一次运行需要55秒。 第二个需要2秒。 两个结果集是相同的。 为什么这个提示会带来如此惊人的性能提升? 的在线丛书条目RECOMPILE未提供详细的解释: 指示SQL Server数据库引擎在执行后放弃为查询生成的计划,从而迫使查询优化器在下次执行同一查询时重新编译查询计划。在不指定RECOMPILE的情况下,数据库引擎缓存查询计划并重新使用它们。编译查询计划时,RECOMPILE查询提示将使用查询中任何局部变量的当前值;如果查询在存储过程中,则将当前值传递给任何参数。 当只需要重新编译存储过程中的一部分查询而不是整个存储过程时,RECOMPILE是创建使用WITH RECOMPILE子句的存储过程的有用替代方法。有关更多信息,请参见重新编译存储过程。创建计划指南时,RECOMPILE也很有用。有关更多信息,请参见使用计划指南优化已部署应用程序中的查询。 由于我的查询有很多局部变量,因此我猜测当我使用OPTION (RECOMPILE)查询提示时,SQL Server能够(严重)优化它。 我到处看的人都说OPTION (RECOMPILE)应该避免。对此的解释通常是,使用此提示,SQL Server无法重用此执行计划,因此必须浪费时间每次重新编译它。(但是)鉴于巨大的性能优势,我倾向于认为这次使用此查询提示将是一件好事。 我应该使用它吗?如果没有,是否有一种方法可以强制SQL Server在没有此提示且不更改应用程序的情况下使用更好的执行计划?

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.