我在我的测试表添加了一个普通索引,但是查看执行计划,它并没有走索引,数据量为百万级别,请问这是什么原因呀
CREATE INDEX index_test_table ON test_table_221010 (file_name);
select * from pg_indexes where tablename='test_table_221010';
EXPLAIN select * from test_table_221010 where file_name = 'testFileName';
可以这样做下验证:
-- 加下analyze
EXPLAIN analyze select * from test_table_221010 where file_name = 'testFileName';
set enable_seqscan = off;
EXPLAIN analyze select * from test_table_221010 where file_name = 'testFileName';
【if】如果第二个执行计划走索引了,那问题就是代价评估的问题了,优化器认为你的全表扫代价更低。
可以贴下对比执行计划我看看。
【else】如果第二个执行计划没走索引,那问题就不是代价了,就是索引、编码字符集或其他问题导致的 一定走不了这个索引。
CREATE INDEX index_test_table ON test_table_221010 using hash(file_name);
先测试下索引是否会开始减少查询时间
EXPLAIN ANALYZE SELECT * FROM test_table_221010 WHERE file_name = 'Blake';
1、看了前面的回答,不知道题主使用的PG是什么版本的?
2、我在12版本的PG数据库中,有一张300万数据量的表,为一个varchar(255)的字段task_id_建立了btree索引,然后执行一个简单的SELECT语句:
CREATE INDEX idx_tblxxx_task_id ON public.tblxxx USING btree (task_id_)
执行计划:
EXPLAIN SELECT * FROM tblxxx WHERE task_id_ = 'd1015f30-ee6b-11e9-924a-b2932425b87c';
执行计划结果:
Bitmap Heap Scan on tblxxx (cost=5.61..531.87 rows=136 width=2200)
Recheck Cond: ((task_id_)::text = 'd1015f30-ee6b-11e9-924a-b2932425b87c'::text)
-> Bitmap Index Scan on idx_tblxxx_task_id (cost=0.00..5.57 rows=136 width=0)
Index Cond: ((task_id_)::text = 'd1015f30-ee6b-11e9-924a-b2932425b87c'::text)
实际执行:
EXPLAIN ANALYZE SELECT * FROM tblxxx WHERE task_id_ = 'd1015f30-ee6b-11e9-924a-b2932425b87c';
实际执行结果:
Bitmap Heap Scan on tblxxx (cost=5.61..531.87 rows=136 width=2200) (actual time=0.019..0.021 rows=3 loops=1)
Recheck Cond: ((task_id_)::text = 'd1015f30-ee6b-11e9-924a-b2932425b87c'::text)
Heap Blocks: exact=2
-> Bitmap Index Scan on idx_tblxxx_task_id (cost=0.00..5.57 rows=136 width=0) (actual time=0.016..0.016 rows=3 loops=1)
Index Cond: ((task_id_)::text = 'd1015f30-ee6b-11e9-924a-b2932425b87c'::text)
Planning Time: 0.073 ms
Execution Time: 0.036 ms
照理说pg数据库会选择cost最小的执行计划,但影响数据库判定执行计划的因素有很多,如果就是一简单的普通表,执行计划应该正常才对,这种不正常的结果一个是考虑某些数据库参数配置不对或者系统资源不足等等,另一个就是考虑数据库版本过低了……
之后我又试了一下不走索引的模糊匹配,速度勉强可以接受(一普通的刀片机开发服务器):
EXPLAIN ANALYZE SELECT * FROM tblxxx WHERE task_id_ ~ 'd1015f30';
执行结果:
Gather (cost=1000.00..78831.41 rows=222 width=2200) (actual time=0.143..752.197 rows=3 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on tblxxx (cost=0.00..77809.21 rows=92 width=2200) (actual time=495.514..744.273 rows=1 loops=3)
Filter: ((task_id_)::text ~ 'd1015f30'::text)
Rows Removed by Filter: 1134806
Planning Time: 0.247 ms
Execution Time: 752.214 ms
不要用select *,换成具体字段试试
两种可,一是你重复得太多了;二是查询得结果超过总数得百分 之15 ,都会使索引失效