【问题标题】:Does index work when query like 'where created_at > ?'像“where created_at > ”这样的查询时索引是否有效?
【发布时间】:2014-05-03 21:45:36
【问题描述】:

我正在使用 Postgresql,需要进行类似“WHERE created_at > ?”的查询。我不确定索引是否适用于此类查询。

我做了一个实验。在 created_at 列上添加索引后,我解释了以下 2 个查询。

1)

EXPLAIN SELECT * FROM categories WHERE created_at > '2014-05-03 21:34:27.427505';

结果是

QUERY PLAN
------------------------------------------------------------------------------------
 Seq Scan on categories  (cost=0.00..11.75 rows=47 width=528)
   Filter: (created_at > '2014-05-03 21:34:27.427505'::timestamp without time zone)

2)

EXPLAIN SELECT * FROM categories WHERE created_at = '2014-05-03 21:34:27.427505';

结果是

                                            QUERY PLAN
---------------------------------------------------------------------------------------------------
 Index Scan using index_categories_on_created_at on categories  (cost=0.14..8.16 rows=1 width=528)
   Index Cond: (created_at = '2014-05-03 21:34:27.427505'::timestamp without time zone)

请注意,第一个使用“过滤器”,而第二个使用“索引条件”,根据 Postgresql 的文档,前者只是逐一扫描,而后者使用索引。

它是否表示像“created_at >”这样的查询?不会通过在“created_at”列上添加索引来固定?


更新

我使用的是Rails 4.0,根据控制台,索引是由

CREATE  INDEX  "index_categories_on_created_at" ON "categories"  ("created_at")

【问题讨论】:

  • 您是如何创建索引的?
  • @univerio,我更新了我的帖子
  • 一切似乎都是对的,所以我唯一能想到的就是表中数据的选择性。见this question
  • 请注意,通常最好使用包含下限 (>=),而不是独占下限。在处理所有连续范围类型时,保存上界的独占。
  • 如果 Postgres 选择了错误的查询计划,this related answer might help.

标签: mysql sql ruby-on-rails postgresql ruby-on-rails-4


【解决方案1】:

时间戳上的索引通常响应范围查询,即 >、

只有在认为使用索引比不使用索引要快的情况下,PostgreSQL 才会使用索引(就此而言,如果有多个索引可用,它会尝试选择最快的索引来使用)。它期望从 > 查询中返回的那 47 行有多少表?如果答案是“表的 10%”,那么 Postgres 不会打扰索引。就此而言,查询规划器很少使用索引来扫描非常小的表,因为如果您的整个表适合 3 个数据页,那么扫描整个表会更快。

如果你愿意,你可以很容易地玩这个。

1) 使用 EXPLAIN ANALYZE 而不仅仅是 EXPLAIN,这样您就可以比较查询规划器的预期与实际得到的结果。

2) 使用以下任何语句关闭和打开索引和表扫描:

SET enable_seqscan = false; --turns off table scans
SET enable_indexscan = false; -- turns of index scans
SET enable_bitmapscan = false; -- turns off bitmap index scans

如果你玩过,你会发现使用索引实际上更慢。

【讨论】:

    【解决方案2】:

    使用索引意味着读取索引加上从表中读取选定的行。需要权衡的是,仅读取表格会更有效。 DBMS 用来为任何给定查询选择哪个更好的算法通常非常好(尽管并不完美)。

    很可能(并且很可能)不使用索引是更好的选择这个查询

    使用@Clockwork-Muse AND @univerio 建议来获得选择性通常是一个好主意,尽管在这种情况下由于表大小可能无关紧要。您也可以使用ORDER BY created_at 来查看它是否会影响计划。

    实验(根据@FuzzyChef)可以帮助找到权衡点。使用不同的表格大小并更改其他变量以查看结果。

    【讨论】:

      猜你喜欢
      • 2019-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-25
      • 2019-12-24
      • 2015-06-24
      • 1970-01-01
      相关资源
      最近更新 更多