pg_query_params和部分索引

时间:2012-03-02 10:46:07

标签: php postgresql indexing

对{(相当旧的)PHP 5.3.10数据库使用PostgreSQL 8.2.23

我正在使用这样的查询:

SELECT * FROM mytable WHERE status = 1 AND id = 123456;

我创建了一个部分索引来提高性能:

CREATE INDEX i1 ON mytable (id) WHERE status = 1;

问题是,当我使用pg_query_params时,似乎没有使用部分索引(并且查询非常慢):

pg_query_params('SELECT * FROM mytable WHERE status = $1 AND id = $2', array(1,123456));

我在PostgreSLQ 9.1数据库上测试相同的PHP代码,它似乎运行良好(使用了索引)。不幸的是,我目前无法升级到9.1。对我来说,更快的解决方法似乎不使用部分索引...

对于旧版本的PG,pg_query_params和部分索引是否有任何已知限制? 除了在使用pg_query_params

时避免部分索引之外,我还有其他解决方法吗?

编辑:

这是8.2.23服务器和9.1.2服务器上的执行计划。 执行的查询(通过PHP)是:

EXPLAIN ANALYZE SELECT * FROM mytable WHERE status = $1 AND id = $2

但是,奇怪的行为,当真正执行查询(我的意思是在PG 9.1上使用pg_prepare删除“EXPLAIN ANALYZE”)时,查询似乎没有使用索引(症状:查询非常慢,几秒......就像seq扫描!?)。

PG 8.2,使用pg_query_params:

Seq Scan on mytable  (cost=0.00..289976.55 rows=1 width=6) (actual time=851.956..3112.038 rows=1 loops=1)

PG 8.2,使用pg_prepare + pg_execute:

Seq Scan on mytable  (cost=0.00..289976.55 rows=1 width=6) (actual time=399.486..1595.102 rows=1 loops=1)

PG 9.1,使用pg_query_params:

Index Scan using i1 on mytable  (cost=0.00..9.61 rows=1 width=6) (actual time=0.046..0.047 rows=1 loops=1)

PG 9.1,使用pg_prepare + pg_execute:

Index Scan using i1 on mytable  (cost=0.00..9.61 rows=1 width=6) (actual time=0.043..0.043 rows=1 loops=1)

=>但正如我所说,PG 9.1上最后一次pg_execute的实际持续时间是1'860 ms !!

1 个答案:

答案 0 :(得分:1)

准备好的陈述的问题在于,在准备期间,它不知道以后会有什么价值。索引条件表示WHERE status = 1,但查询是否具有“status = 1”值?很难预测。

对于这样的查询,使用预准备语句,两个条件的索引可能是最佳性能选项:

CREATE INDEX idx_id_status ON mytable (id, status);

这也适用于版本8.2和9.1。