我有一个 SQL Server 2012 数据库。我注意到Reason for early termination of statement optimization一些查询的值,并且都给出了Good Enough Plan Found. 现在我的问题是:
是否有 DMV 或扩展事件来列出由于找到 Good Enough Plan 以外的原因而终止优化的所有查询?我参考了以下两篇文章,其中没有列出完整的可能性列表。[此外,他们在我的数据库中给了我不同的结果]。
我写了两个函数来回答七周内七个数据库中第 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 movies ON (movies.movie_id = movies_actors.movie_id)
UNION ALL
SELECT
searches.title AS entity_term,
suggestions.movie_id AS suggestion_id,
suggestions.title AS suggestion_title,
RANK() OVER (PARTITION BY searches.movie_id ORDER BY …Run Code Online (Sandbox Code Playgroud) 2020-08-04 更新:
由于显然仍在定期查看此答案,因此我想提供有关情况的最新信息。我们目前正在使用带有表分区的 PG 11,timestamp并且可以轻松处理表中的数十亿行。仅索引扫描可以挽救生命,没有它就不可能。
使用 PostgreSQL 9.2,我在相对较大的表(200 多万行)上进行慢速查询时遇到问题。我没有尝试任何疯狂的事情,只是增加了历史价值。下面是查询和查询计划输出。
我的表布局:
Table "public.energy_energyentry"
Column | Type | Modifiers
-----------+--------------------------+-----------------------------------------------------------------
id | integer | not null default nextval('energy_energyentry_id_seq'::regclass)
prop_id | integer | not null
timestamp | timestamp with time zone | not null
value | double precision | not null
Indexes:
"energy_energyentry_pkey" PRIMARY KEY, btree (id)
"energy_energyentry_prop_id" btree (prop_id)
"energy_energyentry_prop_id_timestamp_idx" btree (prop_id, "timestamp")
Foreign-key constraints:
"energy_energyentry_prop_id_fkey" FOREIGN KEY (prop_id) REFERENCES gateway_peripheralproperty(id) DEFERRABLE INITIALLY DEFERRED
Run Code Online (Sandbox Code Playgroud)
数据范围从2012-01-01至今,新数据不断增加。prop_id外键中大约有 2.2k 个不同的值,均匀分布。
我注意到行估计值相差不远,但成本估计值似乎大了 …
postgresql performance index optimization postgresql-performance
考虑到优化器不能花它需要的所有时间(它必须最小化执行时间而不是贡献它)来探索所有可能的执行计划,它有时会被切断。
我想知道这是否可以覆盖以便您可以在需要时(或一定数量的毫秒)始终提供优化器。
我不需要这个(atm),但我可以想象一个场景,一个复杂的查询在一个紧密的循环中执行,你想提出最佳计划并事先缓存它。
当然,你有一个紧密的循环,你应该重写查询,这样它就会消失,但请耐心等待。
这更多是出于好奇而提出的问题,也是为了查看短路优化和完整优化之间有时是否存在差异。
事实证明,您可以使用跟踪标志 2301 为优化器提供更多时间。这不完全是我所要求的,但它很接近。
我在这方面找到的最佳信息是Ian Jose 的SQL Server 2005 SP1中的查询处理器建模扩展。
小心使用这个跟踪标志!但是在提出更好的计划时它会很有用。也可以看看:
我正在考虑具有大量连接的查询,其中连接顺序的解决方案空间呈指数级增长。SQL Server 使用的启发式方法非常好,但我想知道如果优化器有更多时间(在几秒甚至几分钟的范围内),它是否会提出不同的顺序。
这可能属于意见范畴,但我很好奇人们是否使用跟踪标志 4199作为 SQL Server 的启动参数。对于使用过它的人,您在什么情况下遇到过查询回归?
这似乎是全面的潜在性能优势,我正在考虑在我们的非生产环境中全局启用它,并让它静置几个月以找出任何问题。
2014 年(或 2016 年)是否默认将 4199 中的修复程序纳入优化器?虽然我理解不引入意外计划更改的情况,但在版本之间隐藏所有这些修复似乎很奇怪。
我们使用的是 2008、2008R2,主要是 2012。
在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.)
Run Code Online (Sandbox Code Playgroud)
这里似乎提到了这样的事情: MySQL 实例停滞“做 SYNC 索引”
我的问题是:当在日志中看到此注释时,应该采取什么措施(如果有)?
MySQL 和操作系统版本:
mysql-community-server- 5.7.9 -1.el7.x86_64
centos-release-7-1.1503.el7.centos.2.8.x86_64
运行SHOW VARIABLES LIKE 'innodb%'; 如建议所示:
innodb_page_cleaners | 1
Run Code Online (Sandbox Code Playgroud) 我最近看到了“where 1=1 statement”这个问题;为了编写更清晰的代码(从宿主语言的角度),我在构建动态 SQL 时经常使用的 SQL 构造。
一般来说,添加到 SQL 语句中是否会对查询性能产生负面影响?我不是在寻找关于特定数据库系统的答案(因为我已经在 DB2、SQL Server、MS-Access 和 mysql 中使用过它)——除非在不了解细节的情况下不可能回答。
我们需要每晚在我们的 SQL Server 2008 R2 上做一些报告。计算报告需要几个小时。为了缩短时间,我们预先计算了一个表格。该表是基于 JOINining 12 个相当大(数千万行)的表创建的。
直到几天前,这个聚合表的计算才用了大约 4 个小时。我们的 DBA 将这个大连接拆分为 3 个较小的连接(每个连接 4 个表)。临时结果每次都保存到一个临时表中,供下次join使用。
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 0
When TQ.[QuestionPoints] > 0 Then 1
Else 0 End
,WrongAnswer …Run Code Online (Sandbox Code Playgroud) 我有一个有 2 列的表格。两列的类型都设置为varchar(38)。如果我为其中一列创建一个值为空的行,它是否会占用与该值不为空相同的存储空间?
换句话说,当创建一行时,MySQL 是否会为该列保留存储空间(取决于其类型)?
我有一张这样的表:
CREATE TABLE Updates
(
UpdateId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
ObjectId INT NOT NULL
)
Run Code Online (Sandbox Code Playgroud)
本质上是跟踪 ID 增加的对象的更新。
该表的使用者将选择一个由 100 个不同对象 ID 组成的块,按UpdateId特定的UpdateId. 本质上,跟踪它停止的位置,然后查询任何更新。
我发现这是一个有趣的优化问题,因为我只能通过编写由于索引而碰巧做我想要的查询来生成最大优化的查询计划,但不保证我想要什么:
SELECT DISTINCT TOP 100 ObjectId
FROM Updates
WHERE UpdateId > @fromUpdateId
Run Code Online (Sandbox Code Playgroud)
@fromUpdateId存储过程参数在哪里。
有以下计划:
SELECT <- TOP <- Hash match (flow distinct, 100 rows touched) <- Index seek
Run Code Online (Sandbox Code Playgroud)
由于UpdateId正在使用索引上的搜索,结果已经很好,并且按照我想要的从最低到最高的更新 ID 排序。这会生成一个流程不同的计划,这就是我想要的。但是排序显然不能保证行为,所以我不想使用它。
这个技巧也会产生相同的查询计划(尽管有一个冗余的 TOP):
WITH ids AS
(
SELECT ObjectId
FROM Updates …Run Code Online (Sandbox Code Playgroud) performance sql-server optimization sql-server-2014 query-performance
optimization ×10
sql-server ×5
performance ×3
mysql ×2
postgresql ×2
index ×1
innodb ×1
join ×1
logs ×1