我有table
CREATE TABLE IF NOT EXISTS employeedb.employee_tbl
(
id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
dm_company_id integer NOT NULL,
customer_employee_id text NOT NULL),
personal_mobile text,
CONSTRAINT employee_pkey PRIMARY KEY (id),
CONSTRAINT employee_id_company_constraint UNIQUE (dm_company_id, customer_employee_id)
和索引上personal_移动的类
CREATE INDEX company_id_personal_mobile_index ON employeedb.employee_tbl (dm_company_id, personal_mobile COLLATE "C");
现在当我点击以下查询时
explain analyse select * from employeedb.employee_tbl where dm_company_id = 2011 and employee_tbl.personal_mobile like '+1%';
我总是看到使用employee_id_company_constraint
索引。
Index Scan using employee_id_company_constraint on employee_tbl (cost=0.14..8.16 rows=1 width=641) (actual time=0.056..0.093 rows=2 loops=1)
Index Cond: (dm_company_id = 2011)
Filter: (personal_mobile ~~ '+1%'::text)
Rows Removed by Filter: 28
Planning Time: 0.951 ms
Execution Time: 0.173 ms
为什么Postgres不使用比employee_id_company_constraint
更高效的company_id_personal_mobile_index
来进行上述查询?
1条答案
按热度按时间blmhpbnm1#
我们无法从您的计划中看到一条重要信息,即它 * 认为 * 筛选器将删除多少行。这些重要数据没有报告。
您可以执行此查询,以探查供需规划员认为正在进行的作业:
我们需要知道它期望从这个简化的查询中找到多少行,以及它实际找到多少行(但假定它实际找到30行,即找到的2行+从当前计划中筛选出的28行)。
如果它认为
dm_company_id = 2011
只匹配1行,那么使用更复杂的索引来决定是否使用该行是没有意义的(根据计划者当前的思维方式),只测试这一行并查看应该更快。如果我的理论是正确的,那么问题就变成了,为什么它期望找到1行,而真实的的答案是30?也许你的统计数据已经过时了,也许发生了其他事情。
ANALYZE
应该修复第一个问题,第二个问题需要更多的研究--在我的理论得到证实并且ANALYZE无法纠正问题之前,这是不必要的。