当像'where created_at>这样的查询时,索引是否有效?

时间:2014-05-03 21:45:37

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

我正在使用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)

请注意,第一个使用'Filter',而第二个使用'Index Cond',根据Postgresql的文档,前者只是一个一个扫描,而后者是使用索引。 / p>

是否表示查询类似'created_at> ?不会通过在'created_at'列上添加索引来固定?


更新

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

创建的
CREATE  INDEX  "index_categories_on_created_at" ON "categories"  ("created_at")

2 个答案:

答案 0 :(得分:2)

时间戳上的索引通常响应范围查询,即>,<,之间,< =等。但是,正如univero指出的那样,选择性和成本估算起着重要作用。

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

如果你玩,你可以看到使用索引的位置实际上更慢。

答案 1 :(得分:1)

使用索引意味着读取索引并从表中读取所选行。需要权衡的是,仅仅读取表格就可以更有效率。 DBMS用于选择哪个更适合任何给定查询的算法通常都很好(虽然不完美)。

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

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

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