我正在 MySQL 5.1.53 中进行一些实验,并且遇到了一个我只是不明白的情况。
CREATE TABLE A (
`pk` INT(11) NOT NULL,
`fk` INT(11) NOT NULL,
PRIMARY KEY `pk_A` (`pk`),
KEY `idx_fk` (`fk`)
) ENGINE=INNODB;
SET foreign_key_checks=0;
ALTER TABLE `A` ADD FOREIGN KEY `idx_fk` (`fk`) REFERENCES `parent` (`pk`);
Run Code Online (Sandbox Code Playgroud)
据我所知,这应该只会将约束添加到表元数据中以供将来的数据执行,并且应该是 O(1) 操作 - 我们已经使用“SETforeign_key_checks=0”关闭了实际检查约束并且它应该使用 idx_fk 索引(在 ADD FOREIGN KEY 子句中指定 - 可能是多余的),因此它不必创建任何内容或以任何方式迭代数据。
然而,当我运行 ALTER TABLE 时,表越大,该操作就越慢。
它在做什么以及为什么这么慢?
此执行计划具有以下内存部分:
Memory fraction input:1, Memory Fraction Output:1.
这是一个非常简单的查询:
SELECT [a].[activityId],
[a].[title],
[a].[description],
[a].[inclusions],
[d].[path],
[d].[uploadToBucket],
[a].[imageUriMain],
[a].[locationId]
FROM [dbo].[activity] AS a
LEFT JOIN [dbo].[document] AS d
ON d.documentId = a.documentId
AND d.activityId = a.activityId
ORDER BY title ASC
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,什么是内存分数以及如何摆脱它们(或排序运算符)?
performance sql-server optimization execution-plan query-performance performance-tuning
我正在尝试优化这个表值函数。如果可以,我会将其更改为程序,但我不能。问题在于两个更新语句。我只在函数中保留了这两个,因为它们导致了主要的性能问题。我将第一个从外部应用重写为内部连接,我查看了统计数据,发现它们是错误的,所以我添加了一个选项(重新编译),它有很大帮助。问题出在第二次更新中。统计有误,不知道如何制定合适的执行计划,并通过提示进行优化。你知道如何缩短时间吗?我试图索引表变量,但没有结果。
这是一个执行计划https://www.brentozar.com/pastetheplan/?id=B1EdBo5e4
谢谢。
CREATE FUNCTION [dbo].[cfn_PlanServis_Seznam](
@IDVazRole INT,
@IDUzivatel INT,
@IDRole INT,
@IDLokalita INT,
@lCid INT
)
RETURNS @PlanServis TABLE(
lIDAuto INT,
szSPZ VARCHAR(100),
lDepozit INT,
szTypVozidla varchar(100),
szTypServisu NVARCHAR(300),
szServisniPlan NVARCHAR(300),
lZbyvaDni INT,
lZbyvaKm INT,
lNajetoKm INT,
dtServis DATETIME,
dcZbyvaMotohodin DECIMAL(15,1),
dcNajetoMotohodin DECIMAL(15,1),
IDVazPlanServisAuto INT,
IDPlanServisDefinice INT,
lBarva INT
)
AS
BEGIN
DECLARE @Auto TABLE(
lIDAuto INT,
szSPZ VARCHAR(100),
szTyp VARCHAR(100),
IDCisTypServis INT,
szTypServisu NVARCHAR(500),
szServisniPlan NVARCHAR(500),
lKmStart INT,
dtStart DATETIME,
lKmPriZavedeni INT,
lUjetoPredZavedenim INT,
dcMotohodinyStart DECIMAL(15,1),
lIntervalKm …Run Code Online (Sandbox Code Playgroud) performance sql-server optimization t-sql execution-plan query-performance
回答这个问题,
鉴于此表(根据问题构建):
CREATE TABLE wordcount (id SERIAL NOT NULL PRIMARY KEY, description TEXT NOT NULL);
INSERT INTO wordcount (description) VALUES ('What a great day');
INSERT INTO wordcount (description) VALUES ('This is a product. It is useful');
Run Code Online (Sandbox Code Playgroud)
产生这个结果:
id | word_count | unique_word_count | Description
---------+------------+-------------------+---------------
1 | 4 | 4 | What a great day
2 | 7 | 6 | This is a product. It is useful
Run Code Online (Sandbox Code Playgroud)
我给出了(正确的)答案,你可以在这里找到。
然而,在评论中,OP 然后又问了一个问题——如果有问题的字符串是['a', ' ', ' ', …
postgresql optimization string-manipulation query-performance
在准备我之前的Constant Scan 问题时,我VALUES以各种方式进行了试验,并遇到了关于连接的事情,VALUES这对我来说很奇怪。
设置很简单
CREATE TABLE #data ([Id] int);
INSERT INTO #data VALUES (101), (103);
Run Code Online (Sandbox Code Playgroud)
然后有一个查询
DECLARE @id1 int = 101, @id2 int = 102;
SELECT *
FROM (VALUES (@id1), (@id2)) p([Id])
FULL HASH JOIN #data d ON d.[Id] = p.[Id];
Run Code Online (Sandbox Code Playgroud)
没有什么特别之处。如果你运行它,它会工作并产生它的结果。这是它的执行计划
从VALUES然而删除行
SELECT *
FROM (VALUES (@id1)) p([Id])
FULL HASH JOIN #data d ON d.[Id] = p.[Id];
Run Code Online (Sandbox Code Playgroud)
导致优化器失败
消息 8622,级别 16,状态 1,第 1 行
查询处理器无法生成查询计划...
为什么?有没有办法(除了将参数放入临时表)使用哈希算法使其工作?
注意:这不是真正的设备,用于研究优化器行为和功能。
上面的例子在
Microsoft SQL …
performance sql-server optimization hints sql-server-2016 query-performance
Before Project Normalization 树跟在 Join Collapsed 树之后。
使用大约 250 个查询的样本集 - 和 Traceflags 8605、8606、8607、3604 - 在任何示例查询中,我都没有检测到这两种树之间的任何差异。
是否可以构建一个查询,其中这两棵树之间存在差异?
(这是一篇博客文章的研究 - 我会感谢任何可以提供帮助的人。)
我们使用一些“聚合”视图使用鉴别器从多个表中进行选择(注意:这些视图不是分区视图,因为鉴别器不在基表中)。这在使用 时通常效果很好option(recompile),因为查询计划器将在选择查询计划之前消除不可到达的union all路径。
然而,当将结果选择为标量变量时,这种常量折叠优化似乎失败了。将结果选择到临时表变量中不会对重新编译进行去优化。
下面是SQL Server 2017中的一个复现案例:
-- A table, don't need any data.
create table [test].test_table (col1 int, primary key (col1));
-- A simple 'aggregate' view. Using the same table here is irrelevant and,
-- while the view shows the scenario, it might not be required to reproduce the issue.
create view [test].test_view as
select col1, descrim = 1 from [test].test_table
union all
select col1, descrim = 2 from [test].test_table
Run Code Online (Sandbox Code Playgroud)
普通查询,其结果在优化的查询计划感人只有 …
我有一个报告表(大约 10 亿行)和一个很小的维度表:
CREATE TABLE dbo.Sales_unpartitioned (
BusinessUnit int NOT NULL,
[Date] date NOT NULL,
SKU varchar(8) NOT NULL,
Quantity numeric(10, 2) NOT NULL,
Amount numeric(10, 2) NOT NULL,
CONSTRAINT PK_Sales_unpartitioned PRIMARY KEY CLUSTERED (BusinessUnit, [Date], SKU)
);
--- Demo data:
INSERT INTO dbo.Sales_unpartitioned
SELECT severity AS BusinessUnit,
DATEADD(day, message_id, '2000-01-01') AS [Date],
LEFT([text], 3) AS SKU,
1000.*RAND(CHECKSUM(NEWID())) AS Quantity,
10000.*RAND(CHECKSUM(NEWID())) AS Amount
FROM sys.messages
WHERE [language_id]=1033;
--- Artificially inflate statistics of demo data:
UPDATE STATISTICS dbo.Sales_unpartitioned WITH ROWCOUNT=1000000000;
--- …Run Code Online (Sandbox Code Playgroud) 我的应用程序中的查询之一是超时。使用 SQL Server 分析器,我能够获得准确的错误 SQL 代码。这是一个sp_executesql动态语句,在服务器上的 SSMS 中运行时间超过 2 分钟。相比之下,临时运行相同的 SQL - 在外面sp_executesql但仍然有参数 - 只需要 600 毫秒。
查看缓存的执行计划,这 2 个查询具有完全相同的查询哈希但不同的计划。我 DBCC FREEPROCCACHEd 准备好的(慢的)希望接下来的执行可以重用临时的快速查询的计划。但事实并非如此。运行 sp_executesql 查询总是重新弹出一个新的、缓慢的计划。
按照此处的指南,我研究了参数嗅探的可能性。才发现我的4个参数在两个执行计划中完全一样。
我还尝试OPTION (RECOMPILE)更新相关表的统计信息,但没有结果。
执行计划有 2 个非常相似的主要分支,除了较慢的一个在分支的连接处有嵌套循环,而快速的没有。较低的分支叶子是两个计划中的索引扫描,除了较慢的一个读取数百万行,而较快的一个读取数千行。
在较快的索引的使用上没有明显的区别。顶部分支的组织方式略有不同。
准备好的查询可以重用临时缓存的执行计划吗?是什么导致了如此巨大的性能差异?
optimization ×10
sql-server ×7
performance ×3
foreign-key ×1
hints ×1
mysql ×1
postgresql ×1
recompile ×1
t-sql ×1