【问题标题】:Selection by primary key and other indexes按主键和其他索引选择
【发布时间】:2015-12-15 07:33:54
【问题描述】:

假设我的表中有数百万行。该表在 id 列上具有主键(pk 在 postgresql 中默认为索引)。

该表还有一些额外的列,如yearnamephone 和其他内容。

我想按 id 或一组 id 和 year 这样的列查找行:

SELECT * 
FROM mytable 
WHERE year = '1996' AND id = 123123

或类似:

SELECT * 
FROM mytable 
WHERE year = '1996' AND id IN (123123, 456456, 789789)

如果我在id 上有主键,我应该在year 列上创建索引吗?对于这种情况,哪种索引更有效?

如果我的表中只有两年(例如 1996 年和 1997 年),如果我在 year 列上创建索引会更好吗?

【问题讨论】:

  • 不要比较数字和字符串。 '1996' 是字符串值,而不是数字。如果您不使用与列的数据类型匹配的常量值,则某些 DBMS 可能不会使用索引查找(尽管对于“数百万”行中的两个不同年份,无论如何都很难选择索引)。
  • 这适用于哪个 RDBMS?请添加标签以指定您使用的是mysqlpostgresqlsql-serveroracle 还是db2 - 或者完全是其他东西。

标签: sql postgresql indexing


【解决方案1】:

为您的场景创建索引没有意义。 ID 是主键,当您将其与年份混合时(使用 AND),将始终使用 ID 上的索引。

【讨论】:

  • 至少和年份一样。 (或将是完全不同的东西。)
  • @jarlh 是的。但 OP 并没有询问 OR。当有 OR 并且表中只有 2 年的值时,将使用 FULL SCAN。
  • 我只是想添加额外的信息,因为你说“与年份混合”。很高兴知道这取决于您的混音方式。
  • 好的,我添加了说明。
  • @Leonard 按索引访问数据意味着读取一行。当您进行完全扫描时,您会在一次访问期间读取多行。读取整个表可能比仅对一年中仅 100 个不同的值使用索引更有效。另一个故事是按年份对表格进行分区。对于您的最后一个场景,这将是最有效的。
【解决方案2】:

1) 如果您定义了 PK,则不需要仅针对该字段的索引。 http://www.postgresql.org/docs/current/interactive/sql-createtable.html

"PostgreSQL 自动为每个唯一约束和主键约束创建索引以强制唯一性。因此,没有必要为主键列显式创建索引。"

2) 但是,如果您需要定期对年份和 id 进行排序,我建议您创建一个包含两者的索引。我发现当你以正确的方式获得索引的顺序时,PG 表现更好,例如我有一个包含 store_number 和 product_number 的表,它在多个商店中有相同的产品。首先使用 store_number 效果要好得多,因为这是用户查询的常用过滤器,并且将记录集减少了数百万 - 产品比商店多!

3) 我建议将年份更改为整数。更容易进行逻辑运算。

【讨论】:

    猜你喜欢
    • 2021-08-26
    • 2014-07-26
    • 2018-05-10
    • 1970-01-01
    • 1970-01-01
    • 2021-08-23
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多