select * from table where username="johndoe"
在 Postgres 中,如果 username 不是主键,我知道它会遍历所有记录。
但是如果是主键字段,上面的SQL语句会遍历整个表,还是匹配username就终止。换句话说,当“where”在主键列上运行时,它的行为是否有所不同?
当这些列用作过滤谓词时,主键(以及所有索引列)利用索引,例如WHERE
和JOIN...ON
子句。
作为一个真实世界的示例,我的应用程序有一个名为 的表Log_Games
,该表以数百万行ID
作为主键,以及许多其他非索引列,例如ParsedAt
. 比较以下内容:
索引查询
EXPLAIN ANALYZE
SELECT *
FROM "Log_Games"
WHERE "ID" = 792046
索引查询计划
Index Scan using "Log_Games_pkey" on "Log_Games" (cost=0.43..8.45 rows=1 width=4190) (actual time=0.024..0.024 rows=1 loops=1)
Index Cond: ("ID" = 792046)
Planning time: 1.059 ms
Execution time: 0.066 ms
非索引查询
EXPLAIN ANALYZE
SELECT *
FROM "Log_Games"
WHERE "ParsedAt" = '2015-05-07 07:31:24+00'
非索引查询计划
Seq Scan on "Log_Games" (cost=0.00..141377.34 rows=18 width=4190) (actual time=0.013..793.094 rows=1 loops=1)
Filter: ("ParsedAt" = '2015-05-07 07:31:24+00'::timestamp with time zone)
Rows Removed by Filter: 1924676
Planning time: 0.794 ms
Execution time: 793.135 ms
带有 indexed 子句的查询使用 index Log_Games_pkey
,导致查询在 0.066 毫秒内执行。带有非索引子句的查询恢复为顺序扫描,这意味着它从表的开始到结束查看哪些列匹配,该操作导致执行时间激增至 793.135 毫秒。
网络上有很多很好的资源可以帮助您阅读执行计划并决定何时可能需要支持索引。一个很好的起点是 PostgreSQL 文档:https : //www.postgresql.org/docs/9.6/static/using-explain.html
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句