我们的 Postgres 性能下降到原来的 1/4,我们不知道为什么。
我们有两台具有相同硬件的机器(我们称它们为 A 和 B):
Intel(R) Xeon(R) CPU E5-4640 0 @ 2.40GHz (64 cores)
384 GB RAM
15k SAS, 16 disk RAID 10 array
Run Code Online (Sandbox Code Playgroud)
每台机器都有基本相同的 Postgres 集群,大约有 100 GB 的数据库,具有以下设置:
version: PostgreSQL 9.4.4 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11), 64-bit
bytea_output: escape
checkpoint_completion_target: 0.7
checkpoint_segments: 256
checkpoint_timeout: 30min
client_encoding: UTF8
cpu_index_tuple_cost: 0.001
cpu_operator_cost: 0.0005
cpu_tuple_cost: 0.003
DateStyle: ISO, MDY
default_text_search_config: pg_catalog.english
dynamic_shared_memory_type: posix
effective_cache_size: 128GB
from_collapse_limit: 4
hot_standby: on
join_collapse_limit: 4
lc_messages: …Run Code Online (Sandbox Code Playgroud) performance database-tuning postgresql-9.4 performance-tuning postgresql-performance
我有一个巨大的表(> 30 亿行,总计 3 TB),使用 Postgres 9.5 定义如下:
CREATE TABLE user_events
(
user_id VARCHAR NOT NULL,
datetime BIGINT NOT NULL,
field1 VARCHAR,
field2 VARCHAR,
field3 VARCHAR,
field4 VARCHAR,
field5 VARCHAR,
CONSTRAINT user_events_user_id_datetime_pk PRIMARY KEY (user_id, datetime)
);
alter table user_events set (autovacuum_vacuum_cost_delay=10);
Run Code Online (Sandbox Code Playgroud)
我需要大约每秒 2000 次查询这个表,但我无法进行足够的并行化(我达到了大约一半)。
使用以下准备好的语句,我得到了合理的(我想)响应时间:
PREPARE getact AS select * from user_events where user_id = $1 order by datetime limit 1000;
explain analyze EXECUTE getact('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx');
Run Code Online (Sandbox Code Playgroud)
CREATE TABLE user_events
(
user_id VARCHAR NOT NULL,
datetime BIGINT NOT NULL,
field1 VARCHAR, …Run Code Online (Sandbox Code Playgroud) postgresql performance postgresql-9.5 query-performance performance-tuning
这可能是愚蠢的,感觉就像我要回去尝试理解基础知识。
所以我创建了一个如下所示的测试表并在其上创建一个聚集索引
create table test( c1 int)
DECLARE @Random INT;
DECLARE @Upper INT;
DECLARE @Lower INT
SET @Lower = 1
SET @Upper = 10000
while 1=1
begin
SELECT @Random = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)
insert into test SELECT @Random
end
create clustered index cidx on test(c1)
Run Code Online (Sandbox Code Playgroud)
现在我使用实际执行计划运行以下查询
DECLARE @Min INT
SET @Min = 216 --selected this cause this was a histogram step
select * from test where c1 = @Min
select * from test where …Run Code Online (Sandbox Code Playgroud) performance sql-server sql-server-2014 query-performance performance-tuning
我运行了一个产生 25 个线程的多线程客户端来进行并发 API 调用并将数据插入到 AWS Aurora 服务器。
一段时间后,我开始看到超时错误:lock wait timeout exceeded try restarting transaction.我们对运行 MySQL 5.6.10 的服务器运行相同的测试,并没有发生锁等待超时。
有没有办法避免这种超时?
在 AWS Aurora 服务器上,SHOW ENGINE INNODB STATUS显示:
---TRANSACTION 8530565676, ACTIVE 81 sec setting auto-inc lock
mysql tables in use 2, locked 2
LOCK WAIT 6 lock struct(s), heap size 376, 2 row lock(s), undo log entries 1
MySQL thread id 405, OS thread handle 0x2ae270b03700, query id 11045 10.50.101.56 app_migration
INSERT INTO contacts_contactaudit (action,
contact_id,
date_created,
date_updated, …Run Code Online (Sandbox Code Playgroud) 在这个方案中
id uid content
1 1 A
2 1 B
3 1 C
4 1 D
5 1 E
Run Code Online (Sandbox Code Playgroud)
如果用户决定他不需要这些行,id = 3, 4, 5是让他将其设置content为NULL还是删除该行更好?
这个过程发生了很多次而且他可能会NULL再次使用这些插槽。我是否仍然使用UPDATE并将其设置为NULL以防他将来更改它?还是只是DELETE整行?
问题是这样的:最好
DELETE行?INSERT| -> DELETE-> INSERT..DELETE->INSERT
或者
UPDATE行?INSERT| -> UPDATE to NULL-> UPDATE to value.. UPDATE to NULL->UPDATE to value
我们如何从 dm_os_performance_counters DMV 中找到页数/秒,我在这里没有看到它:
SELECT * FROM sys.dm_os_performance_counters
where counter_name like '%page%'
Run Code Online (Sandbox Code Playgroud)
页数/秒 定义:页数/秒计数器指示由于硬页错误而从磁盘检索的页数或由于页错误而写入磁盘以释放工作集中空间的页数。
此执行计划具有以下内存部分:
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
所以我正在调整这个查询,我很确定在这种情况下,我可以用左联接替换内部联接而不影响数据。但是,我不完全确定为什么这会更快。这是查询:
SELECT DISTINCT cl.NAME AS company_name,
cl.id AS company_id,
ep.Plan__c AS plan_id,
ep.Employee__c,
ep.id,
do.Subcategory__c,
ep.Plan_Type__c,
pt.SubType,
Sum((pt.[shares] * fvh.[ValuePerShare])) AS TotalValue,
ppe.Deferral_Option__c,
dt.Defer_type_Code,
do.Short_Code__c,
pt.ContributionYear
FROM dbo.ParticipantTrades pt WITH (NOLOCK)
INNER JOIN dbo.PayoutPathElection ppe WITH (NOLOCK)
ON pt.payoutPathElectionID = ppe.Id
INNER JOIN dbo.DeferralOption do WITH (NOLOCK)
ON ppe.Deferral_Option__c = do.id
INNER JOIN dbo.EmployeePlan ep WITH (NOLOCK)
ON pt.employeePlan = ep.Id
LEFT JOIN dbo.DeferralType dt WITH (NOLOCK)
ON pt.deferralType = dt.defID
INNER JOIN dbo.Fnc_lastfundvalue('2019-01-30') AS fvh
ON pt.fund = fvh.Fund …Run Code Online (Sandbox Code Playgroud) 存在一个“批量查询”表,它有两列(BatchID、RecordID),它们都是 TSQL 类型的“uniqueidentifier”。唯一的聚簇键在(BatchID,RecordID)上,并且没有二级索引。
我们使用 SqlBulkCopy 将数千或数百万个 id 快速插入到单个批处理 id 下的表中,以便各种查询可以加入它以使用与该批处理关联的记录 id 集执行过滤。这种方法比尝试多个查询快得多,所有查询都在查询字符串中发送 id 列表。查询完成后,该批记录 ID 将被删除。当没有查询运行时,该表平均为空,但可能有数百个活动批次,因为我们每秒处理数千个可能使用该表的 API 请求。
我的问题是,DBA 需要什么样的维护步骤(如果有)来维护这些表。例如,它是否会从定期索引重建中受益,或者 SQL Server 是否会自行处理已删除行的清理(释放页块等)。此外,表或聚集索引是否有任何特殊配置会有所帮助,特别是考虑到标识符是随机 Guids(唯一标识符)。
一般我们使用最新版本的SQL Server,企业版。有些服务器在 Azure 中,有些在 AWS 中。
我也有兴趣听取替代方案。例如,我认为这种方法最适合永久表,但我也可以创建一个会话本地临时表作为事务的一部分,该表在完成时被删除,而不是从永久表中插入和删除行。我只是不知道相比之下会如何表现。
performance sql-server delete index-maintenance bulk-insert performance-tuning
我们有很多:
select count(*) from TBL where XDATE between ? and ? and FLD = ?;
Run Code Online (Sandbox Code Playgroud)
我们希望通过调整XDATE列(具有DATE类型)上的索引来提高性能。
什么类型的索引更适合DATE类型和条件之间?
performance ×10
sql-server ×5
delete ×2
mysql ×2
aurora ×1
bulk-insert ×1
index ×1
innodb ×1
optimization ×1
oracle ×1
postgresql ×1
select ×1
timeout ×1