inc*_*kka 2 sql database csv postgresql performance
我有一个Postgre SQL数据库表,其中包含超过500万条目.还有一个包含100,000个条目的CSV文件.
我需要运行一个查询来从DB获取与CSV文件数据相关的数据.
然而,根据每个人的理解和我自己的经验,这种查询需要很长时间才能完成.(超过6个小时,根据我的猜测)
因此,根据最新的研究结果和工具,我们是否有更好,更快的解决方案来执行同样的任务?
该快速通道:创建一个临时表(可能使用现有表作为模板,方便),并使用相匹配的CSV文件的结构COPY:
CREATE TEMP TABLE tmp(email text);
COPY tmp FROM 'path/to/file.csv';
ANALYZE tmp; -- do that for bigger tables!
Run Code Online (Sandbox Code Playgroud)
我假设 CSV中的电子邮件是唯一的,您没有指定.如果不是,使他们独特的:
CREATE TEMP TABLE tmp0
SELECT DISTINCT email
FROM tmp
ORDER BY email; -- ORDER BY cheap in combination with DISTINCT ..
-- .. may or may not improve performance additionally.
DROP TABLE tmp;
ALTER TABLE tmp0 RENAME TO tmp;
Run Code Online (Sandbox Code Playgroud)
对于您的特定情况,电子邮件中的唯一索引是有序的.在加载和清理数据后创建索引要高效得多.通过这种方式,COPY如果存在欺骗行为,您还可以防止以独特的违规行为挽救:
CREATE UNIQUE INDEX tmp_email_idx ON tmp (email);
Run Code Online (Sandbox Code Playgroud)
第二个想法,如果您只是更新大表,则根本不需要临时表上的索引.它将按顺序读取.
是DB表使用主键编制索引.
在这种情况下唯一相关的索引:
CREATE INDEX tbl_email_idx ON tbl (email);
Run Code Online (Sandbox Code Playgroud)
作出这样CREATE UNIQUE INDEX ...如果可能的话.
要更新您的表格,请在以后的评论中详细说明:
UPDATE tbl t
SET ...
FROM tmp
WHERE t.email = tmp.email;
Run Code Online (Sandbox Code Playgroud)
所有这些都可以很容易地包装到plpgsql或sql函数中.
请注意,如果要参数化文件名,则COPY需要EXECUTE在plpgsql函数中使用动态SQL .
默认情况下,会话结束时会自动删除临时表.
相关回答:
如何批量插入PostreSQL中的新行