如何在sql表上设置正确的索引?

如何在sql表上设置正确的索引?,sql,database,postgresql,Sql,Database,Postgresql,如何识别值得在sql表上设置的索引 以以下为例: select * from products where name = 'car' and type = 'vehicle' and availability > 3 and insertion_date > '2015-10-10' order by price asc limit 1 想象一个有几百万条目的数据库。 如果我对WHERE和orderby子句中出现的所有属性的组合设置索引,会有什么好处 例如

如何识别值得在
sql
表上设置的索引

以以下为例:

select * 
from products 
where name = 'car' 
  and type = 'vehicle' 
  and availability > 3 
  and insertion_date > '2015-10-10' 
order by price asc 
limit 1
想象一个有几百万条目的数据库。 如果我对
WHERE
orderby
子句中出现的所有属性的组合设置索引,会有什么好处

例如:

create index i_my_idx on products
   (name, type, availability, insertion_date, price)

你设置索引的方式绝对正确。索引与ORDERBY子句无关

SQL查询设计中的几个要点

  • 始终将条件放在WHERE子句的第一位,该子句将过滤最大行数,例如上面的查询name='car'将过滤产品中的最大记录数

  • 不要使用“>=”只使用“>”,因为如果失败的等于,则“大于”或“等于”将始终首先检查“大于”,这将降低查询性能

  • 按照where子句的排列顺序创建单个索引

  • 试着使用ANY来最小化IN子句

  • 谢谢
    Anant

    在决定索引哪些列时,有一些经验法则非常有用:

  • 确保主键上有一个唯一的索引-这是在大多数RDBMS(包括postgresql)中指定PK时自动完成的
  • 为每个外键添加索引。在某些RDBMS中,当您指定FK而不是在postgresql中指定FK时,会自动创建它们
  • 如果PK是复合键,考虑在每个FK上添加索引来构成PK(除了第一个,由PK索引覆盖)。如图2所示,一些RDBMS(例如带有ISAM的MySQL)在指定FKs时会自动添加这些索引
  • 通常,但并非总是,查询中的表联接将是PF到FK的,通过在两个键上都有索引,RDBMS的查询优化器可以灵活地确定最佳计划以获得最大性能。但这并不总是最好的,有经验的程序员通常会为数据库查询格式化SQL,以影响执行计划以获得最佳性能,或者决定省略他们知道不需要的索引。值得注意的是,在一个RDBMS上是最优的SQL查询在另一个RDBMS上,或者在DB服务器的未来版本上,或者随着数据库的增长,并不一定是最优的。后者很重要,因为在某些RDBMS(如postgres和Oracle)中,查询执行计划取决于表中的数据(这称为基于成本的优化)

    一旦你解决了这些问题,很多问题就归结为经验和对数据的了解,更重要的是,如何访问数据

    一般来说,您将寻找索引那些最擅长过滤数据的列。在上面的查询中,最明显的是
    name
    。这可能足以使查询运行得足够快(除非您的所有产品都是汽车)

    除此之外,还值得列出访问数据的常用方式,例如:

  • 获取属于某一类别的产品列表-在
    类别上的索引可能会有所帮助
  • 但是,获取当前可用的产品列表-关于可用性的索引可能没有帮助,因为大部分
    产品可能满足此条件
  • 除非您正在处理大量数据,否则这通常就是您所需要做的全部工作,而且通常情况下,添加索引“以防万一”不是一个好主意,因为维护它们会有开销。但是,如果您的系统确实存在性能问题,那么值得考虑如何在查询中使用列的组合,阅读有关postgres查询优化器的信息等等


    并回答你的最后一个问题——可能是,但这远不是第一件要考虑的事情。

    是这个PostgreSQL特定的建议,还是一般的?而且,“索引与顺序BY条款无关”的说法也不正确。索引可以帮助数据库对结果进行排序。不能使用单个示例查询来确定正确的索引。您需要对所有查询进行概述,这些查询最频繁,最重要。这也取决于你的其他设置。有多少写操作(具体是什么操作)?数据分布、基数、资源等,不能说“sql表”。SQL是查询语言,一个表就是一个表,如果你愿意的话就是一个“数据库表”。@a_horse_,with_no_name:实际上,只要索引的所有列上都有相等条件,哪一列先到并不重要。在这种情况下,我们有范围和平等。因此,所呈现索引中列的顺序是好的。@a_horse_,没有名称感谢您的详细评论,我明白了。那么,让我们再举一个航班的例子:在
    出发\机场
    到达\机场
    中添加一个索引可能会更好。假设我得到一个1k条目的结果集。如果将例如索引放在离开日期上,而对于特定日期可能只有10个条目,会有进一步的好处吗?对于基本的经验法则,请阅读and。“确保主键上有唯一的索引”-在Postgres中PK上不可能没有索引或非唯一索引您的“少数规则”这些都不好。1.毫无意义,PK是在Postgres中使用唯一的btree索引自动实现的。(非常清楚,Postgres允许在同一列上创建另一个索引),独特与否,但这将是毫无意义的、昂贵的浪费。2.基本上是正确的。3.没有根据。通常,多列索引足够好,它是为PK自动创建的,在大多数情况下为FK创建索引是有意义的。如果您没有其他要求,则不需要对密钥的某些部分创建其他索引。这些是规则对于学习的人来说,你和我可能会做不同的事情。@Sonic:答案的其余部分很有用,但你主要的“几条规则”大多是不正确的