不同的索引用于具有不同 companyid 的相同查询
Different Indexes are used for same query with different companyid's
我们在我们的 RDS 实例上 运行 以下查询,它花费了大量时间,并且对于不同的 companyId
它在一秒钟内执行。
查询:
select *
from items_1_primary
WHERE items_1_primary.item_type_id IN (1,2)
AND items_1_primary.hidden IS NULL
AND items_1_primary.company_id = 9130347227057236
ORDER BY items_1_primary.id
LIMIT 1 OFFSET 0;
仅供参考这是两个不同公司的查询计划
inventorymigrationprod=> explain analyze select * from items_1_primary WHERE items_1_primary.item_type_id IN (1,2) AND items_1_primary.hidden IS NULL AND items_1_primary.company_id =9130347227057236 ORDER BY items_1_primary.id LIMIT 1 OFFSET 0;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.57..1894.58 rows=1 width=332) (actual time=372100.718..372100.719 rows=1 loops=1)
-> Index Scan using items_1_primary_pkey on items_1_primary (cost=0.57..175867668.27 rows=92855 width=332) (actual time=372100.717..372100.717 rows=1 loops=1)
Filter: ((hidden IS NULL) AND (item_type_id = ANY ('{1,2}'::numeric[])) AND (company_id = '9130347227057236'::numeric))
Rows Removed by Filter: 535927031
Planning Time: 1.626 ms
Execution Time: 372100.745 ms
(6 rows)
inventorymigrationprod=> explain analyze select * from items_1_primary WHERE items_1_primary.item_type_id IN (1,2) AND items_1_primary.hidden IS NULL AND items_1_primary.company_id =9130348260181756 ORDER BY items_1_primary.id LIMIT 1 OFFSET 0;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=10659.77..10659.77 rows=1 width=332) (actual time=9.559..9.560 rows=1 loops=1)
-> Sort (cost=10659.77..10665.38 rows=2242 width=332) (actual time=9.557..9.558 rows=1 loops=1)
Sort Key: id
Sort Method: top-N heapsort Memory: 25kB
-> Index Scan using items_1_primary_company_id_item_type_id on items_1_primary (cost=0.57..10648.56 rows=2242 width=332) (actual time=0.057..6.117 rows=10823 loops=1)
Index Cond: ((company_id = '9130348260181756'::numeric) AND (item_type_id = ANY ('{1,2}'::numeric[])))
Filter: (hidden IS NULL)
Planning Time: 0.138 ms
Execution Time: 9.589 ms
(9 rows)
数据库实例:inventory-migration-prod-cluster
Indexes On Table
--------------------------
indexes:
“items_1_primary_pkey” PRIMARY KEY, btree (id)
“items_1_primary_company_id_item_type_id” btree (company_id, item_type_id)
“items_1_primary_uniqueness” UNIQUE CONSTRAINT, btree (company_id, item_id)
要么 PostgreSQL 高估了满足条件的行数,要么它们在 table.
中以不利的方式分布
如果是第一种情况,加ANALYZE
(也许加上default_statistics_target
)就可以解决问题。
但是无论是什么原因导致的问题,您都可以通过更改 ORDER BY
子句使 PostgreSQL 无法使用索引来避免它:
ORDER BY items_1_primary.id + 0
我们在我们的 RDS 实例上 运行 以下查询,它花费了大量时间,并且对于不同的 companyId
它在一秒钟内执行。
查询:
select *
from items_1_primary
WHERE items_1_primary.item_type_id IN (1,2)
AND items_1_primary.hidden IS NULL
AND items_1_primary.company_id = 9130347227057236
ORDER BY items_1_primary.id
LIMIT 1 OFFSET 0;
仅供参考这是两个不同公司的查询计划
inventorymigrationprod=> explain analyze select * from items_1_primary WHERE items_1_primary.item_type_id IN (1,2) AND items_1_primary.hidden IS NULL AND items_1_primary.company_id =9130347227057236 ORDER BY items_1_primary.id LIMIT 1 OFFSET 0;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.57..1894.58 rows=1 width=332) (actual time=372100.718..372100.719 rows=1 loops=1)
-> Index Scan using items_1_primary_pkey on items_1_primary (cost=0.57..175867668.27 rows=92855 width=332) (actual time=372100.717..372100.717 rows=1 loops=1)
Filter: ((hidden IS NULL) AND (item_type_id = ANY ('{1,2}'::numeric[])) AND (company_id = '9130347227057236'::numeric))
Rows Removed by Filter: 535927031
Planning Time: 1.626 ms
Execution Time: 372100.745 ms
(6 rows)
inventorymigrationprod=> explain analyze select * from items_1_primary WHERE items_1_primary.item_type_id IN (1,2) AND items_1_primary.hidden IS NULL AND items_1_primary.company_id =9130348260181756 ORDER BY items_1_primary.id LIMIT 1 OFFSET 0;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=10659.77..10659.77 rows=1 width=332) (actual time=9.559..9.560 rows=1 loops=1)
-> Sort (cost=10659.77..10665.38 rows=2242 width=332) (actual time=9.557..9.558 rows=1 loops=1)
Sort Key: id
Sort Method: top-N heapsort Memory: 25kB
-> Index Scan using items_1_primary_company_id_item_type_id on items_1_primary (cost=0.57..10648.56 rows=2242 width=332) (actual time=0.057..6.117 rows=10823 loops=1)
Index Cond: ((company_id = '9130348260181756'::numeric) AND (item_type_id = ANY ('{1,2}'::numeric[])))
Filter: (hidden IS NULL)
Planning Time: 0.138 ms
Execution Time: 9.589 ms
(9 rows)
数据库实例:inventory-migration-prod-cluster
Indexes On Table
--------------------------
indexes:
“items_1_primary_pkey” PRIMARY KEY, btree (id)
“items_1_primary_company_id_item_type_id” btree (company_id, item_type_id)
“items_1_primary_uniqueness” UNIQUE CONSTRAINT, btree (company_id, item_id)
要么 PostgreSQL 高估了满足条件的行数,要么它们在 table.
中以不利的方式分布如果是第一种情况,加ANALYZE
(也许加上default_statistics_target
)就可以解决问题。
但是无论是什么原因导致的问题,您都可以通过更改 ORDER BY
子句使 PostgreSQL 无法使用索引来避免它:
ORDER BY items_1_primary.id + 0