此执行计划具有以下内存部分:
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
我有一个存储过程,它在 12/11 之前运行良好,平均执行时间不到 2 小时。从周二(12/11)开始,存储过程连续运行了3个多小时,不得不手动杀死并重新运行。
需要注意的一件事是,无论何时运行该特定存储过程,处理器利用率都会高达 95%。我们有描述相同的 SQLMonitor 工具 -
为了消除参数嗅探的可能性,我清除了 proc 缓存,DBCC FREEPROCCACHE并在美国东部标准时间上午 5:30 再次通过删除并重新创建它来重新运行该过程。即使在此之后,处理器利用率也会出现峰值。以下是清除 proc 缓存后的当前处理器利用率 -
以下是存储过程仅供参考 -
CREATE PROCEDURE [dbo].[Build_Base02_Orders]
AS
BEGIN
SET NOCOUNT ON;
declare @Start_Date datetime = getdate();
declare @Last_Date datetime
DECLARE @PROMOHIGHDATE INT = (SELECT MAX(FILE_DATE) FROM Stage1_Promotion);
--Create the Orders from Items
drop table WinstonBrand_Base.dbo.Orders;
With OrdersBase1 as
(
Select * from WinstonBrand.dbo.Stage3_Orders Orders
UNION ALL
Select * from …Run Code Online (Sandbox Code Playgroud) 我正在尝试优化这个表值函数。如果可以,我会将其更改为程序,但我不能。问题在于两个更新语句。我只在函数中保留了这两个,因为它们导致了主要的性能问题。我将第一个从外部应用重写为内部连接,我查看了统计数据,发现它们是错误的,所以我添加了一个选项(重新编译),它有很大帮助。问题出在第二次更新中。统计有误,不知道如何制定合适的执行计划,并通过提示进行优化。你知道如何缩短时间吗?我试图索引表变量,但没有结果。
这是一个执行计划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
我有一个看起来像这样的查询:
SELECT post.id, post.author_id, post.published_at, post.content
FROM post
WHERE post.group_id = 1
ORDER BY post.published_at DESC, post.id
LIMIT 5;
Run Code Online (Sandbox Code Playgroud)
(group_id, published_at DESC, id)当没有使用行级别安全性 (RLS) 策略时,此查询具有一个索引,该索引为其提供此查询计划。
Limit (cost=0.14..1.12 rows=5 width=143)
-> Index Scan using post_published_at on post (cost=0.14..15.86 rows=80 width=143)
Index Cond: (group_id = 1)
Run Code Online (Sandbox Code Playgroud)
然后我添加这个策略:
CREATE POLICY select_member_of ON post FOR SELECT USING
(EXISTS (SELECT 1
FROM group_member
WHERE group_member.account_id = current_setting('current_account_id', false)::INT AND
group_member.group_id = post.group_id));
Run Code Online (Sandbox Code Playgroud)
有在化合物主键group_member.account_id和group_member.group_id上group_member表中。
我希望Postgres的计划此查询为仅索引扫描的group_member,因为这两个group_member.account_id和 …
postgresql performance execution-plan row-level-security explain query-performance
假设我有一张桌子:
-- just for test purposes
CREATE TABLE SomeTable (
ID INT IDENTITY(1,1) NOT NULL CONSTRAINT PK__SomeTable__ID PRIMARY KEY CLUSTERED
,SomeColumn1 NVARCHAR(50) NULL
,SomeColumn2 DATETIME NULL
);
-- populate table with some rows
INSERT INTO SomeTable DEFAULT VALUES;
GO 1000
Run Code Online (Sandbox Code Playgroud)
因为第三方应用程序有一个视图将表的 ID 列从INT到NVARCHAR(假设它是必须的):
CREATE VIEW ThirdPartyView AS
SELECT
ID = CAST(ID as NVARCHAR(10))
,C1 = SomeColumn1
,C2 = SomeColumn2
FROM SomeTable;
Run Code Online (Sandbox Code Playgroud)
然后当我通过 ID 访问一行时,我得到一个 INDEX SCAN:
SELECT *
FROM ThirdPartyView
WHERE ID = N'1'
Run Code Online (Sandbox Code Playgroud)
我明白为什么。
我该怎么做才能在查询之外获得 …
performance sql-server execution-plan view type-conversion query-performance
Postgres 似乎总是使用顺序扫描,它可以使用部分索引来仅获取索引扫描。它仅在一个从句超过 100 个元素时发生。
鉴于下表:
create table foo(id bigint primary key, bar bigint);
insert into foo (id, bar)
select g.id, case when id % 1000 = 0 then id else null end
from generate_series(1, 10000000) AS g (id) ;
--Create partial index
create unique index ix_foo_bar on foo(bar) where bar is not null;
analyze foo;
Run Code Online (Sandbox Code Playgroud)
并给出以下带有大语句的查询:
explain analyze select count(*) from foo where bar in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101);
Run Code Online (Sandbox Code Playgroud)
查询计划显示顺序扫描。它很慢,而且成本很高:
QUERY PLAN
------------------------------------
Finalize Aggregate (cost=612955.35..612955.36 rows=1 width=8) (actual time=254.605..254.605 rows=1 loops=1)
-> …Run Code Online (Sandbox Code Playgroud) 鉴于这种
declare @Data table (id int, fact char(1));
declare @Summary table (id int, collected varchar(99));
insert @Data(id, fact)
values
(1, 'a'),
(1, 'b'),
(2, 'c'),
(2, 'd'),
(2, 'e');
-- Form a list of unique id values
insert @Summary(id, collected) select distinct id, '' from @Data;
-- Accumulate the fact values into collected
update s
set collected = collected + d.fact
from @Summary as s
inner join @Data as d
on d.id = s.id;
select * from @Summary;
Run Code Online (Sandbox Code Playgroud)
我曾预料
id …Run Code Online (Sandbox Code Playgroud) 我有一些查询需要获取 64 个以上的特定行,例如这个带有 65 个 ID 的示例。TableID 为主键,类型为 BigInt。
SELECT * FROM TableA
WHERE TableID IN (260905384, 260915601, 260929877, 260939625, 260939946, 261096977, 261147037, 261152934, 261163936, 261357728, 261369122, 261376714, 261454472, 261488500, 261527284, 261584786, 261619749, 261679560, 261777653, 261786639, 261795246, 261795810, 261803724, 261821199, 261824173, 261827397, 261840197, 261848595, 261874545, 261889122, 261889355, 261929793, 261953069, 262106609, 262134069, 262134088, 262339745, 262354363, 262360015, 262571936, 262586920, 262591486, 262663776, 262703601, 262746674, 262792439, 262801544, 262826561, 262933229, 262933270, 262947539, 262958110, 263021588, 263032875, 263037208, 263039292, 263045038, 263085369, 263089147, 263091427, 263097644, 263100021, 263103339, 263104396, …Run Code Online (Sandbox Code Playgroud) 下面的查询使用 StackOverflow2010 示例数据库:
DECLARE @Id INT = 18471
SELECT c.UserId FROM dbo.Comments AS c
INNER HASH JOIN dbo.Users AS u
ON c.UserId = u.Id
AND c.UserId = @Id
Run Code Online (Sandbox Code Playgroud)
使用散列连接提示,它返回以下错误:
由于此查询中定义的提示,查询处理器无法生成查询计划。在不指定任何提示且不使用 SET FORCEPLAN 的情况下重新提交查询
当我添加时它有效 OPTION(RECOMPILE)用字符串文字或替换变量。
什么可能导致这个问题?
我正在努力说服查询计划按照我认为应该的方式行事。在查询索引视图时添加 TOP 子句会导致次优计划,我希望在排序方面得到一些帮助。
环境
设置:
首先,我创建了一个视图来回报每个人的高声誉:
CREATE VIEW vwHighReputation
WITH SCHEMABINDING
AS
SELECT [Id],
[DisplayName],
[Reputation]
FROM [dbo].[Users]
WHERE [Reputation] > 10000
Run Code Online (Sandbox Code Playgroud)
接下来,由于我将按显示名称进行搜索,因此我在视图上创建了几个索引:
CREATE UNIQUE CLUSTERED INDEX IX_Users_Id ON [dbo].[vwHighReputation]([Id])
GO
CREATE NONCLUSTERED INDEX IX_Users_DisplayName ON [dbo].[vwHighReputation]([DisplayName]) INCLUDE (Reputation)
GO
Run Code Online (Sandbox Code Playgroud)
如果我通过视图查询,我可以看到我的非聚集索引正在被使用:
SELECT *
FROM [dbo].[vwHighReputation]
WHERE [DisplayName] LIKE 'J%'
Run Code Online (Sandbox Code Playgroud)
计划:(https://www.brentozar.com/pastetheplan/?id=Sy2EoJaiv)
到现在为止还挺好。我什至可以使用我的视图作为带有 OUTER APPLY 的更复杂查询的一部分,并且我仍然只对索引进行了 63 次读取(这显然是一个人为的示例,但有助于说明我将要解决的问题) ):
SELECT [U].[Id],
[A].[Reputation],
[A].[DisplayName]
FROM [dbo].[Users] AS [U]
OUTER APPLY (
SELECT * …Run Code Online (Sandbox Code Playgroud) execution-plan ×10
sql-server ×8
performance ×4
optimization ×2
parameter ×2
postgresql ×2
view ×2
explain ×1
hints ×1
index ×1
t-sql ×1
update ×1
where ×1