我从昨天开始就打击了这个问题,而且我并不知道发生了什么:
我正在为数据仓库项目填充维度模式,使用Pentaho Kettle执行"维度查找/更新",它基本上查找维度表中的现有行,插入不包含维度表的现有行存在并返回技术密钥。
维度表本身非常简单:
CREATE TABLE dim_loan
(
_tech_id INTEGER NOT NULL,
loan_id INTEGER,
type TEXT,
interest_rate_type TEXT,
_dim_project_id integer,
_validity_from date,
_validity_to date,
_version integer,
PRIMARY KEY (_tech_id)
);
CREATE INDEX dim_loan_pk_idx ON dim_loan USING btree (_tech_id);
CREATE INDEX dim_loan_compound_idx ON dim_loan USING btree (loan_id, _dim_project_id, _validity_from, _validity_to);
在流程结束时,该表应包含大约650k行。转换开始快速(ish),大约1500行/秒。 当表格有大约5万行时,性能稳定下降到50行/秒。 Kettle看起来像这样的查询:
SELECT _tech_id, _version, "type" AS "Loan Type", interest_rate_type AS int_rate, _validity_from, _validity_to FROM "public".dim_loan WHERE loan_id = $1 AND _dim_project_id = $2 AND $3 >= _validity_from AND $4 < _validity_to
查询计划程序估计执行时间为0.1毫秒:
"Index Scan using dim_loan_compound_idx on dim_loan (cost=0.42..7.97 rows=1 width=42) (actual time=0.043..0.043 rows=0 loops=1)"
" Index Cond: ((loan_id = 1) AND (_dim_project_id = 2) AND ('2016-01-01'::date >= _validity_from) AND ('2016-01-01'::date < _validity_to))"
"Total runtime: 0.078 ms"
当然,实际执行时间大不相同,大约10毫秒,这是不可接受的。使用auto_explain启用慢查询日志我看到频率条目增加如下:
Seq Scan on dim_loan (cost=0.00..2354.21 rows=12 width=52)
Filter: (($3 >= _validity_from) AND ($4 < _validity_to) AND (_dim_project_id = $2) AND ((loan_id)::double precision = $1))
< 2016-12-18 21:30:19.859 CET >LOG: duration: 14.260 ms plan:
Query Text: SELECT _tech_id, _version, "type" AS "Loan Type", interest_rate_type AS int_rate, _validity_from, _validity_to FROM "public".dim_loan WHERE loan_id = $1 AND _dim_project_id = $2 AND $3 >= _validity_from
AND $4 < _validity_to
不管怎么说都不能讲述整个故事,因为不仅这些查询运行缓慢,而且所有查询都运行缓慢。 当然我试着将内存参数调整到愚蠢的数量而没有真正的性能差异,我也尝试了最新的9.6,它表现出与9.3相同的行为,这就是我正在使用的。
在具有相同索引的MySQL数据库上,相同的转换从头到尾以5000行/秒的速度运行。我真的想要使用PG而且我确信这是一件微不足道的事,但是什么!? 也许是jdbc驱动程序的东西?我确认它确实一直使用单个连接,因此它甚至不是连接开销问题...
答案 0 :(得分:2)
刚刚发现原因确实是贷款ID被强制转换为双倍,这当然使得索引无用!原因是Kettle对此列的元数据做出了错误的假设,该列来自excel文件。 现在性能与MySQL相当!快乐的日子