Postgres 如何触发机制规模?
我们有一个大型的 PostgreSQL 安装,我们正在尝试使用日志表和 TRIGGER(s) 来实现一个基于事件的系统。
基本上,我们希望为每个我们希望收到更新/插入/删除操作通知的表创建一个 TRIGGER。一旦触发此触发器,它将执行一个函数,该函数将简单地将一个新行(对事件进行编码)附加到一个日志表中,然后我们将从外部服务轮询该日志表。
在全面使用 Postgres TRIGGER(s) 之前,我们想知道它们是如何扩展的:我们可以在单个 Postgres 安装上创建多少个触发器?它们会影响查询性能吗?有没有人试过这个?
我有以下查询:
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
Run Code Online (Sandbox Code Playgroud)
上述查询在三秒内完成。
如果上面的查询返回任何值,我们希望存储过程退出,因此我将其重写如下:
If Exists(
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
)
Begin
Raiserror('Source missing',16,1)
Return
End
Run Code Online (Sandbox Code Playgroud)
但是,这需要 10 分钟。
我可以像下面这样重写上面的查询,它也可以在不到 3 秒的时间内完成:
select databasename
from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source
if @@rowcount >0 …Run Code Online (Sandbox Code Playgroud) performance sql-server sql-server-2012 exists query-performance
我在 PostgreSQL 9.6 查询计划方面遇到了麻烦。我的查询如下所示:
SET role plain_user;
SELECT properties.*
FROM properties
JOIN entries_properties
ON properties.id = entries_properties.property_id
JOIN structures
ON structures.id = entries_properties.entry_id
WHERE structures."STRUKTURBERICHT" != ''
AND properties."COMPOSITION" LIKE 'Mo%'
AND (
properties."NAME" LIKE '%VASP-ase-preopt%'
OR properties."CALCULATOR_ID" IN (7,22,25)
)
AND properties."TYPE_ID" IN (6)
Run Code Online (Sandbox Code Playgroud)
我为上面使用的表启用了行级安全性。
用set enable_nestloop = True,查询规划运行嵌套循环用约37秒的总运行时间加入:https://explain.depesz.com/s/59BR
with set enable_nestloop = False,采用Hash Join方式,查询时间约0.3秒:https : //explain.depesz.com/s/PG8E
我VACUUM ANALYZE在运行查询之前做过,但没有帮助。
我知道这不是一个好的做法set enable_nestloop = False,对于计划者来说,还有任何其他类似的选择。但是我怎样才能“说服”规划器在不禁用嵌套循环的情况下使用散列连接?
重写查询是一种选择。
如果我在绕过 RLS 的角色下运行相同的查询,那么它的执行速度非常快。行级安全策略如下所示:
CREATE POLICY properties_select …Run Code Online (Sandbox Code Playgroud) postgresql performance join row-level-security postgresql-9.6 query-performance
我们有一个大约 1TB 的大型数据库,在强大的服务器上运行 SQL Server 2014。几年来,一切都运行良好。大约 2 周前,我们进行了全面维护,其中包括: 安装所有软件更新;重建所有索引和压缩 DB 文件。但是,我们没想到在某个阶段,在实际负载相同的情况下,DB 的 CPU 使用率会增加超过 100% 到 150%。
经过大量的故障排除,我们将其缩小到一个非常简单的查询,但我们找不到解决方案。查询非常简单:
select top 1 EventID from EventLog with (nolock) order by EventID
Run Code Online (Sandbox Code Playgroud)
它总是需要大约 1.5 秒!但是,使用“desc”的类似查询总是需要大约 0 毫秒:
select top 1 EventID from EventLog with (nolock) order by EventID desc
Run Code Online (Sandbox Code Playgroud)
PTable 大约有 5 亿行;EventID是ASC数据类型为 bigint(身份列)的主聚集索引列(ordered )。顶部有多个线程向表中插入数据(较大的 EventID),底部有 1 个线程删除数据(较小的 EventID)。
在 SMSS 中,我们验证了两个查询始终使用相同的执行计划:
聚集索引扫描;
估计行数和实际行数均为1;
估计和实际执行次数均为1;
估计I/O成本是8500(好像有点高)
如果连续运行,则两者的查询成本相同 50%。
我更新了索引统计with fullscan,问题依旧;我再次重建索引,问题似乎消失了半天,但又回来了。
我打开了 IO 统计:
set statistics io on …Run Code Online (Sandbox Code Playgroud) performance sql-server select sql-server-2014 top query-performance
我现在负责 SQL 开发的同事说我永远不应该使用OR语句,因为它会弄乱查询优化器并忽略产生慢查询的表索引。我在谷歌搜索时找不到任何这样的例子。以下查询的替代方案变得非常难看,其中有十几个代码块看起来几乎相同(对于示例)使用 if else 语句为每个变量状态。请注意检查为短路的变量,如果值为 2,则返回所有结果,否则按字段过滤。
我询问了一些包含这些关于为什么不使用OR语句的声明的资源,并收到了以下链接(我们使用的是 MS SQL Server)。
这些示例似乎都不像当前的实现,如下所示。我发现很难相信这段代码有问题,但如果有问题,请告诉我。我还想了解更多信息,其中关于不使用的评论OR实际上可能适用以及为什么如此,以便更好地理解该问题。
SELECT
e.EmployeeName,
e.DepartmentName,
crs.Title,
c.Name as CompanyName
FROM Employee E
Left Outer Join Company c ON c.Id = @companyId
INNER JOIN Department d on e.DepartmentId = d.Id
WHERE
c.Id = @companyId
AND (@Active = 2 OR crs.IsActive = @Active)
AND (@Dot = 2 OR IsDot = @Dot)
AND crs.CompanyId = @companyId
AND d.CompanyId = @companyId
ORDER BY EmployeeName, Title, …Run Code Online (Sandbox Code Playgroud) 我有两个几乎相同的查询在同一个 SQL Server 2005 实例上运行:
SELECT由 LINQ 生成的原始查询(我知道,我知道......我不是应用程序开发人员,只是 DBA :)。OPTION (RECOMPILE)在最后加了一个。没有其他任何改变。
第一个每次运行需要 55 秒。
第二个需要 2 秒。
两个结果集是相同的。
为什么这个提示会产生如此显着的性能提升?
在线图书条目RECOMPILE没有提供非常详细的解释:
指示 SQL Server 数据库引擎在执行后放弃为查询生成的计划,强制查询优化器在下次执行相同查询时重新编译查询计划。在不指定 RECOMPILE 的情况下,数据库引擎会缓存查询计划并重用它们。编译查询计划时,RECOMPILE 查询提示使用查询中任何局部变量的当前值,如果查询在存储过程中,则将当前值传递给任何参数。
RECOMPILE 是创建使用 WITH RECOMPILE 子句的存储过程的一种有用的替代方法,当必须重新编译存储过程中的查询子集而不是整个存储过程时。有关详细信息,请参阅重新编译存储过程。RECOMPILE 在您创建计划指南时也很有用。有关更多信息,请参阅使用计划指南优化已部署应用程序中的查询。
由于我的查询有很多局部变量,我的猜测是当我使用OPTION (RECOMPILE)查询提示时,SQL Server 能够(认真地)优化它。
我所看到的每个地方都有人说OPTION (RECOMPILE)应该避免这种情况。对此的解释通常是使用此提示 SQL Server 无法重用此执行计划,因此每次都必须浪费时间重新编译它。
(但是)考虑到巨大的性能优势,我倾向于认为这次使用这个查询提示会是一件好事。
我应该使用它吗?如果没有,有没有一种方法可以强制 SQL Server 使用更好的执行计划而无需此提示且无需更改应用程序?
performance sql-server-2005 sql-server optimization query-performance
我有一个查询目前平均需要 2500 毫秒才能完成。我的表很窄,但有 4400 万行。我有什么选择可以提高性能,或者这是否已经达到了最好的效果?
查询
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31';
Run Code Online (Sandbox Code Playgroud)
桌子
CREATE TABLE [dbo].[Heartbeats](
[ID] [int] IDENTITY(1,1) NOT NULL,
[DeviceID] [int] NOT NULL,
[IsPUp] [bit] NOT NULL,
[IsWebUp] [bit] NOT NULL,
[IsPingUp] [bit] NOT NULL,
[DateEntered] [datetime] NOT NULL,
CONSTRAINT [PK_Heartbeats] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
指数
CREATE NONCLUSTERED INDEX …Run Code Online (Sandbox Code Playgroud) 我们拥有庞大的生产数据库,其大小约为 300GB。有什么方法可以提高删除查询的性能?现在删除速度在每分钟1-10k之间,对我们来说非常慢。
我最近遇到了这个问题,在网上找不到任何讨论。
下面的查询
DECLARE @S VARCHAR(1) = '';
WITH T
AS (SELECT name + @S AS name2,
*
FROM master..spt_values)
SELECT *
FROM T T1
INNER JOIN T T2
ON T1.name2 = T2.name2;
Run Code Online (Sandbox Code Playgroud)
总是得到一个嵌套循环计划

尝试使用INNER HASH JOIN或INNER MERGE JOIN提示强制问题会产生以下错误。
由于此查询中定义的提示,查询处理器无法生成查询计划。在不指定任何提示且不使用 SET FORCEPLAN 的情况下重新提交查询。
我找到了一种允许使用散列或合并连接的解决方法 - 将变量包装在聚合中。生成的计划成本显着降低(19.2025 与 0.261987)
DECLARE @S2 VARCHAR(1) = '';
WITH T
AS (SELECT name + (SELECT MAX(@S2)) AS name2,
*
FROM spt_values)
SELECT *
FROM T T1
INNER JOIN T T2 …Run Code Online (Sandbox Code Playgroud) 我station_logs在 PostgreSQL 9.6 数据库中有一个表:
Column | Type |
---------------+-----------------------------+
id | bigint | bigserial
station_id | integer | not null
submitted_at | timestamp without time zone |
level_sensor | double precision |
Indexes:
"station_logs_pkey" PRIMARY KEY, btree (id)
"uniq_sid_sat" UNIQUE CONSTRAINT, btree (station_id, submitted_at)
Run Code Online (Sandbox Code Playgroud)
我试图level_sensor根据submitted_at, 对于每个station_id. 大约有 400 个唯一station_id值,每个station_id.
创建索引之前:
EXPLAIN ANALYZE
SELECT DISTINCT ON(station_id) station_id, submitted_at, level_sensor
FROM station_logs ORDER BY station_id, submitted_at DESC;
Run Code Online (Sandbox Code Playgroud)
唯一(成本=4347852.14..4450301.72行=89宽度=20)(实际时间=22202.080..27619.167行=98循环=1) -> Sort …
postgresql performance greatest-n-per-group postgresql-9.6 query-performance
performance ×9
sql-server ×7
optimization ×4
postgresql ×3
exists ×1
join ×1
scalability ×1
select ×1
top ×1