我用 rails g model project name # with more columns 创建了一个模型
每当我在 sql 查询上运行 explain 时,postgres 从不使用索引。这是为什么?
my_db=# \d projects
Table "public.projects"
Column | Type | Collation | Nullable | Default
-------------+-----------------------------+-----------+----------+--------------------------------------
id | integer | | not null | nextval('projects_id_seq'::regclass)
name | character varying | | |
active | boolean | | not null | true
team_id | integer | | |
created_at | timestamp without time zone | | not null |
updated_at | timestamp without time zone | | not null |
account_id | integer | | |
Indexes:
"projects_pkey" PRIMARY KEY, btree (id)
"index_projects_on_account_id" btree (account_id)
"index_projects_on_team_id" btree (team_id)
Foreign-key constraints:
"fk_rails_b4884d7210" FOREIGN KEY (account_id) REFERENCES accounts(id)
"fk_rails_ecc227a0c2" FOREIGN KEY (team_id) REFERENCES teams(id)
Referenced by:
TABLE "products" CONSTRAINT "fk_rails_7327dd6d39" FOREIGN KEY (project_id) REFERENCES projects(id)
当我搜索时,我得到了这个:
my_db=# explain select name from projects where id = 28;
QUERY PLAN
---------------------------------------------------------
Seq Scan on projects (cost=0.00..2.60 rows=1 width=32)
Filter: (id = 28)
(2 rows)
我向 ActiveRecord 询问索引并得到 false
:
ActiveRecord::Base.connection.index_exists?(:projects, :id)
=> false
projects_pkey
就在 Indexes 下,而 Postgres 正在对项目使用 Seq Scan
。我试图更改查询搜索大于 100000 或小于 100000 的 ID。没关系,它始终使用 Seq Scan
有人可以解释为什么它不使用索引吗?在小型数据集上,这很好。然而,问题来自运行一个连接许多表的查询,并对每个表运行解释仍然使用 Seq Scan
这让我问了。 (关于查询,它是将大约10个表与一些通过表连接起来。数据集并不大,只是很宽)
最佳答案
@Rthi 评论中的链接提供了一些很好的建议!
简而言之,Postgres 也没有使用索引,因为:
- 不能
- 它不认为它会更快
1 不太可能,但如果由于某种原因索引不再存在,则可能是这种情况。
2 的可能性更大。小表的顺序扫描更快!因此,Postgres 的统计数据可能是错误的。如果是这样,您需要进行 ANALYZE(或 VACUUM ANALYZE)以使其更新:https://www.postgresql.org/docs/current/sql-analyze.html
如果您在数据较少的开发数据库上运行这些,那也可以解释它的选择!
有关更多信息,您可以运行 EXPLAIN (ANALYZE, BUFFERS)。有多种工具可以使查看和共享这些内容变得更容易,此处列出:https://wiki.postgresql.org/wiki/Performance_Analysis_Tools#Web_tools
免责声明:我正在研究最近列出的 pgMustard。
关于sql - Rails 生成的迁移模型在执行 where 时从不使用索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57405158/