我试图让 PostgreSQL 积极地自动清空我的数据库。我目前已按如下方式配置自动真空吸尘器:
我注意到自动真空仅在数据库未加载时才会启动,因此我遇到死元组比活元组多得多的情况。有关示例,请参阅随附的屏幕截图。其中一张表有 23 个活动元组,但有 16845 个死元组等待真空。这太疯狂了!

当测试运行完成并且数据库服务器空闲时,自动真空开始,这不是我想要的,因为我希望自动真空在死元组数量超过 20% 活元组 + 50 时启动,因为数据库已经配置。服务器空闲时的自动真空对我来说是无用的,因为生产服务器预计会在持续时间内达到 1000 次更新/秒,这就是为什么即使服务器负载不足我也需要自动真空运行。
有什么我想念的吗?如何在服务器负载较重时强制运行自动吸尘器?
更新
这可能是一个锁定问题吗?有问题的表是通过插入后触发器填充的汇总表。这些表以 SHARE ROW EXCLUSIVE 模式锁定,以防止并发写入同一行。
概念性问题:单个查询是否比连接更快,或者:我应该尝试将客户端所需的所有信息都压缩到一个SELECT 语句中,还是只使用看起来方便的尽可能多的信息?
TL;DR:如果我的联合查询比运行单个查询花费的时间更长,这是我的错还是可以预料的?
首先,我不是很精通数据库,所以可能只是我,但我注意到当我必须从多个表中获取信息时,通过对单个表的多个查询来获取这些信息“通常”更快(也许包含一个简单的内部连接)并在客户端将数据拼凑在一起,以尝试编写一个(复杂的)连接查询,我可以在一个查询中获取所有数据。
我试图把一个非常简单的例子放在一起:
架构设置:
CREATE TABLE MASTER
( ID INT NOT NULL
, NAME VARCHAR2(42 CHAR) NOT NULL
, CONSTRAINT PK_MASTER PRIMARY KEY (ID)
);
CREATE TABLE DATA
( ID INT NOT NULL
, MASTER_ID INT NOT NULL
, VALUE NUMBER
, CONSTRAINT PK_DATA PRIMARY KEY (ID)
, CONSTRAINT FK_DATA_MASTER FOREIGN KEY (MASTER_ID) REFERENCES MASTER (ID)
);
INSERT INTO MASTER values (1, 'One');
INSERT INTO MASTER values (2, 'Two');
INSERT …Run Code Online (Sandbox Code Playgroud) 我很久以前在某个地方读过。这本书指出我们不应该允许在 SQL Server 中使用嵌套视图。我不确定我们不能这样做的原因,或者我可能记得不正确的陈述。
学生们
SELECT studentID, first_name, last_name, SchoolID, ... FROM students
CREATE VIEW vw_eligible_student
AS
SELECT * FROM students
WHERE enroll_this_year = 1
Run Code Online (Sandbox Code Playgroud)
老师
SELECT TeacherID, first_name, last_name, SchoolID, ... FROM teachers
CREATE VIEW vw_eligible_teacher
AS
SELECT * FROM teachers
WHERE HasCert = 1 AND enroll_this_year = 1
Run Code Online (Sandbox Code Playgroud)
学校
CREATE VIEW vw_eligible_school
AS
SELECT TOP 100 PERCENT SchoolID, school_name
FROM schools sh
JOIN
vw_eligible_student s
ON s.SchoolID = sh.SchoolID
JOIN
vw_eligible_teacher t
ON s.SchoolID = t.SchoolID
Run Code Online (Sandbox Code Playgroud)
在我的工作场所,我调查了我们的一个内部数据库应用程序。我检查了对象,发现有两到三层的视图相互堆叠。所以这让我想起了我过去读过的东西。有人可以帮忙解释一下吗?
如果这样做不行,我想知道它仅限于 …
我在某些具有大量可能结果集的数据库查询上遇到了性能问题。
有问题的查询,我AND在 WHERE 子句中有三个
条款的顺序重要吗?
就像,如果我把 ASI_EVENT_TIME 子句放在第一位(因为这会从任何子句中删除大部分结果。
这会改善查询的运行时间吗?
询问:
SELECT DISTINCT activity_seismo_info.*
FROM `activity_seismo_info`
WHERE
activity_seismo_info.ASI_ACTIVITY_ID IS NOT NULL AND
activity_seismo_info.ASI_SEISMO_ID IN (43,44,...,259) AND
(
activity_seismo_info.ASI_EVENT_TIME>='2011-03-10 00:00:00' AND
activity_seismo_info.ASI_EVENT_TIME<='2011-03-17 23:59:59'
)
ORDER BY activity_seismo_info.ASI_EVENT_TIME DESC
Run Code Online (Sandbox Code Playgroud)
查询的解释:
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
| 1 | SIMPLE | act...o | range | act...o_FI_1,act...o_FI_2 | act...o_FI_1 | 5 | NULL | 65412 …Run Code Online (Sandbox Code Playgroud) TL; 博士
由于这个问题一直有意见,我在这里总结一下,这样新人就不必忍受历史:
JOIN table t ON t.member = @value1 OR t.member = @value2 -- this is slow as hell
JOIN table t ON t.member = COALESCE(@value1, @value2) -- this is blazing fast
-- Note that here if @value1 has a value, @value2 is NULL, and vice versa
Run Code Online (Sandbox Code Playgroud)
我意识到这可能不是每个人的问题,但通过突出 ON 子句的敏感性,它可能会帮助您寻找正确的方向。无论如何,原文是为未来的人类学家准备的:
原文
考虑以下简单查询(仅涉及 3 个表)
SELECT
l.sku_id AS ProductId,
l.is_primary AS IsPrimary,
v1.category_name AS Category1,
v2.category_name AS Category2,
v3.category_name AS Category3,
v4.category_name AS Category4,
v5.category_name AS Category5
FROM category c4 …Run Code Online (Sandbox Code Playgroud) 我已经向表中添加了用于搜索结果的索引。我按 ASC 或 DESC 顺序显示结果。那么该列是否应该有索引?我在那个表上还有 2 个索引。对该列建立或不建立索引对性能有何影响?
我想了解为什么在 UAT(3 秒内运行)与 PROD(23 秒内运行)上执行相同查询时会有如此巨大的差异。
UAT 和 PROD 都拥有准确的数据和索引。
询问:
set statistics io on;
set statistics time on;
SELECT CONF_NO,
'DE',
'Duplicate Email Address ''' + RTRIM(EMAIL_ADDRESS) + ''' in Maintenance',
CONF_TARGET_NO
FROM CONF_TARGET ct
WHERE CONF_NO = 161
AND LEFT(INTERNET_USER_ID, 6) != 'ICONF-'
AND ( ( REGISTRATION_TYPE = 'I'
AND (SELECT COUNT(1)
FROM PORTFOLIO
WHERE EMAIL_ADDRESS = ct.EMAIL_ADDRESS
AND DEACTIVATED_YN = 'N') > 1 )
OR ( REGISTRATION_TYPE = 'K'
AND (SELECT COUNT(1)
FROM CAPITAL_MARKET
WHERE EMAIL_ADDRESS = ct.EMAIL_ADDRESS …Run Code Online (Sandbox Code Playgroud) 我有一个相当简单的查询
SELECT TOP 1 dc.DOCUMENT_ID,
dc.COPIES,
dc.REQUESTOR,
dc.D_ID,
cj.FILE_NUMBER
FROM DOCUMENT_QUEUE dc
JOIN CORRESPONDENCE_JOURNAL cj
ON dc.DOCUMENT_ID = cj.DOCUMENT_ID
WHERE dc.QUEUE_DATE <= GETDATE()
AND dc.PRINT_LOCATION = 2
ORDER BY cj.FILE_NUMBER
Run Code Online (Sandbox Code Playgroud)
这给了我可怕的表现(就像从不费心等待它完成一样)。查询计划如下所示:
但是,如果我删除它,TOP 1我会得到一个看起来像这样的计划,它会在 1-2 秒内运行:
下面更正 PK 和索引。
TOP 1更改查询计划这一事实并不让我感到惊讶,我只是有点惊讶它使情况变得更糟。
注意:我已经阅读了这篇文章的结果并理解了 aRow Goal等的概念。我很好奇的是如何更改查询以使其使用更好的计划。目前我正在将数据转储到临时表中,然后从中取出第一行。我想知道是否有更好的方法。
编辑对于事后阅读本文的人,这里有一些额外的信息。
当我开始时,没有其他索引。我在 Correspondence_Journal (Document_Id, File_Number) 上找到了一个
performance sql-server sql-server-2008-r2 query-performance performance-tuning
假设一个主要包含 InnoDB 表的生产 OLTP 系统
任何详述特定status变量和诊断的轶事将不胜感激。
我们有一个社交网站,会员可以在其中相互评价兼容性或匹配度。该user_match_ratings表包含超过 2.2 亿行(9 演出数据或近 20 演出索引)。针对此表的查询通常显示在 slow.log(阈值 > 2 秒)中,并且是系统中记录最频繁的慢查询:
Query_time: 3 Lock_time: 0 Rows_sent: 3 Rows_examined: 1051
"select rating, count(*) as tally from user_match_ratings where rated_user_id = 395357 group by rating;"
Query_time: 4 Lock_time: 0 Rows_sent: 3 Rows_examined: 1294
"select rating, count(*) as tally from user_match_ratings where rated_user_id = 4182969 group by rating;"
Query_time: 3 Lock_time: 0 Rows_sent: 3 Rows_examined: 446
"select rating, count(*) as tally from user_match_ratings where rated_user_id = 630148 group by rating;"
Query_time: …Run Code Online (Sandbox Code Playgroud) performance ×10
mysql ×4
sql-server ×3
index ×1
innodb ×1
join ×1
mysql-5 ×1
order-by ×1
postgresql ×1
tuning ×1
vacuum ×1
view ×1