我应该在哪些列上创建索引

时间:2014-09-28 11:02:54

标签: sql database performance postgresql indexing

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字符串的索引,那么它是否有效且明智?

4 个答案:

答案 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会为你做一些额外的数学计算,以确定每个组件的确切时间。

相关问题