对{(相当旧的)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 !!
答案 0 :(得分:1)
准备好的陈述的问题在于,在准备期间,它不知道以后会有什么价值。索引条件表示WHERE status = 1,但查询是否具有“status = 1”值?很难预测。
对于这样的查询,使用预准备语句,两个条件的索引可能是最佳性能选项:
CREATE INDEX idx_id_status ON mytable (id, status);
这也适用于版本8.2和9.1。