Postgres上的简单查找查询非常慢,在MySQL中速度很快

时间:2016-12-18 21:25:56

标签: postgresql pentaho

我从昨天开始就打击了这个问题,而且我并不知道发生了什么:

我正在为数据仓库项目填充维度模式,使用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驱动程序的东西?我确认它确实一直使用单个连接,因此它甚至不是连接开销问题...

1 个答案:

答案 0 :(得分:2)

刚刚发现原因确实是贷款ID被强制转换为双倍,这当然使得索引无用!原因是Kettle对此列的元数据做出了错误的假设,该列来自excel文件。 现在性能与MySQL相当!快乐的日子