2张表:
countries:
id
short_name ("GE", "AR"...)
long_name
....
banks:
id
name ("NATIONAL BANK OF COUNTRY123"...)
country_id
...
鉴于我经常会做以下类型的查找:
select * from countries c
inner join banks b
on b.country_id = c.id
where c.short_name = ? and b.name = ?
我应该在哪些列上创建索引?我在countries
中计算我应该在short_name
上创建一个额外的索引(id
将保留为主要的自动增量键)。我不知道banks
,如果我在name
创建一个varchar
字符串的索引,那么它是否有效且明智?
答案 0 :(得分:1)
如果这是您的查询:
select *
from countries c inner join
banks b
on b.country_id = c.id
where c.short_name = ? and b.name = ?;
您有两种索引方法。基本思想是SQL引擎将从一个表(扫描)中查找行,然后在另一个表中查找值。
第一种可能性是"扫描" countries
然后在banks
中查找:
countries(name, id)
banks(country_id, short_name)
第二种可能性是"扫描" banks
然后在`countries:
banks(short_name, country_id)
countries(id, name)
实际上哪个更好取决于数据中值的分布。您实际上可以添加两个集合并让SQL引擎决定。
答案 1 :(得分:1)
countries
上的short_name
表格包装箱索引。合并索引(例如(id, short_name)
)是浪费资源 - 为什么:id
是主键 - 唯一,因此第一个组件(id)的查找已经给出一行,第二个组件有什么好处?我认为short_name
也是唯一的,所以(short_name, id)
也一样。
banks
表的其他情况。 country_id
在此处不是唯一的,因此您可以从索引中受益:(country_id, name)
我认为这两个额外的索引足以满足您的查询。
答案 2 :(得分:0)
在列上添加索引,这些索引的数值类似于整数,数据类型的两倍......还有那些在where子句中使用的列,可以有索引......
答案 3 :(得分:0)
找出所需索引的最佳方法是测试它们。我希望你有一个为此目的设置的开发环境,你可以加载生产数据(pg_dump和pg_restore)。
如果您的表格足够小,那么将其编入索引可能没有帮助。例如,您的国家/地区表(假设它是国家/地区列表)可能不需要任何索引。
如果您一直在查询银行名称,银行表格中有> 10K记录,banks(name)
索引将有所帮助。但是,如果您想获得某个国家/地区的银行列表,那么索引banks(country_id)
也会很好。
如果您真的关心您的查询性能,请从没有索引开始并测试每个索引以确定它给出的好处。 PostgreSQL的解析分析工具非常出色,但是使用explain.depesz.com会为你做一些额外的数学计算,以确定每个组件的确切时间。