cal*_*ian 5 postgresql performance index-tuning update amazon-rds postgresql-performance
我在 Amazon RDS(2vCPU,8 GB RAM)上使用 Postgres 9.5。
我使用 pganalyze 来监控我的表现。
我在数据库中有大约 20 万条记录。
在我的仪表板中,我看到以下查询的平均执行时间为 28 秒和 11 秒:
UPDATE calls SET ... WHERE calls.uuid = ? telephonist 28035.41 0.01 100% 0.03%
UPDATE calls SET sip_error = ? WHERE calls.uuid = ? telephonist 11629.89 0.44 100% 0.69%
Run Code Online (Sandbox Code Playgroud)
我已经尝试VACUUM、发现并清理了 7,670 个死行。
任何想法如何提高UPDATE性能?这是查询:
UPDATE calls SET X=Y WHERE calls.uuid = 'Z'
Run Code Online (Sandbox Code Playgroud)
如何改进上述查询?我可以添加另一个字段吗?例子:
UPDATE calls SET X=Y WHERE calls.uuid = 'Z' AND calls.campaign = 'W'
Run Code Online (Sandbox Code Playgroud)
该列uuid未编入索引。
https://www.tutorialspoint.com/postgresql/postgresql_indexes.htm建议不建议将索引用于UPDATE操作。
CREATE TABLE public.calls (
id int4 NOT NULL DEFAULT nextval('calls_id_seq'::regclass),
callsid varchar(128),
call_start timestamp(6) NOT NULL,
call_end timestamp(6) NULL,
result int4 DEFAULT 0,
destination varchar(256),
campaign varchar(128),
request_data varchar(4096),
uuid varchar(128) NOT NULL,
status varchar(64),
duration int4,
recording_file varchar(256),
recording_url varchar(256),
recording_duration int4,
recording_text varchar(4096),
recording_download bool DEFAULT false,
description varchar(4096),
analysis varchar(4096),
is_fax bool DEFAULT false,
is_test bool,
hangup_cause varchar(128),
media_detected bool DEFAULT false,
sip_callid varchar(256),
hangup_cause_override varchar(256),
is_blacklisted bool DEFAULT false,
sip_error varchar(256),
hangup_cause_report varchar(128),
summary varchar(1024)
);
Run Code Online (Sandbox Code Playgroud)
EXPLAIN ANALYZE
SELECT * FROM calls
WHERE calls.uuid='e2ce9eb4-v1lp-p14u-7kkk-lruy-e2ceaae46d';
Run Code Online (Sandbox Code Playgroud)
Seq Scan on call(成本=0.00..16716.25 行=1 宽度=3301)
(实际时间=81.637..81.637 行=0 循环=1)
过滤器:((uuid)::text = 'e2ce9eb4-v1lp-p14u-7kkk-lruy-e2ceaae46d'::text)
过滤器删除的行数:99970
规划时间:0.482 ms
执行时间:81.683 毫秒
Erw*_*ter 10
假设列uuid应该是UNIQUE,这个表定义应该节省一些空间并有助于提高性能:
CREATE TABLE public.calls (
id serial PRIMARY KEY,
result int4 DEFAULT 0 NOT NULL,
uuid uuid UNIQUE NOT NULL -- creates the index you need automatically
call_start timestamp NOT NULL,
call_end timestamp, -- so this can be NULL?
duration int4,
recording_duration int4,
callsid varchar(128),
destination varchar(256),
campaign varchar(128),
request_data varchar(4096),
status varchar(64),
recording_file varchar(256),
recording_url varchar(256),
recording_text varchar(4096),
recording_download bool DEFAULT false,
description varchar(4096),
analysis varchar(4096),
is_fax bool DEFAULT false,
is_test bool,
hangup_cause varchar(128),
media_detected bool DEFAULT false,
sip_callid varchar(256),
hangup_cause_override varchar(256),
is_blacklisted bool DEFAULT false,
sip_error varchar(256),
hangup_cause_report varchar(128),
summary varchar(1024)
);
Run Code Online (Sandbox Code Playgroud)
这里最重要的特性是UNIQUE约束,它是用唯一索引实现的,而索引是你最需要的(比如@ypercube 已经评论过)。
如果uuid不是唯一的,则在其上创建一个普通的 btree 索引。
如果uuid不是有效的 uuid,则将其保留为字符类型 (varchar或text),但仍会创建该索引。
数据类型varchar与 的大小和性能注意事项uuid:
我所有其他建议的更改都是小的改进。详细解释在这里:
如果您不需要强制执行特定的最大长度,我只会将其text用于所有字符列。但这对性能几乎没有任何直接影响。某些列可能会转换为更合适的类型(具有实际的性能优势)。
UPDATE那么为什么那个教程页面会说:
什么时候应该避免索引?
[...]
- 具有频繁、大批量更新或插入操作的表。
这是疏忽的误导。您迫切需要一个索引uuid来支持更新的谓词。所有其他索引都会减慢您的更新速度,因为它们需要额外的工作才能在更新后保持最新状态。因此,如果您没有使用PRIMARY KEYon id(例如允许对其进行 FK 约束),您可以删除它(并uuid改为使用 PK - 也自动索引)。
| 归档时间: |
|
| 查看次数: |
16983 次 |
| 最近记录: |