【问题标题】:Indexing affects only the WHERE clause?索引只影响 WHERE 子句?
【发布时间】:2011-01-05 18:42:43
【问题描述】:

如果我有类似的东西:

CREATE INDEX   idx_myTable_field_x
ON             myTable
USING          btree (field_x);

SELECT COUNT(field_x), field_x FROM myTable GROUP BY field_x ORDER BY field_x;

想象myTable500,000 rows 和大部分field_x 值是唯一的。

由于我不使用任何WHERE 子句,创建的索引对我的查询有任何影响吗?

编辑:我问这个问题是因为在创建索引之前和之后的查询时间之间没有任何相关差异;它们总是需要大约 8 秒(这当然是太多的时间了!)。这是预期的行为吗?

【问题讨论】:

  • 如果完全错误的答案被投票超过唯一正确答案的 2.5 倍,我认为投票系统从根本上被破坏了。 :-(

标签: sql postgresql indexing


【解决方案1】:

索引在这里无济于事,因为无论如何您都在读取整个表,首先进入索引是没有用的(PostgreSQL 还没有仅索引扫描)

因为索引中的几乎所有值都是唯一的,所以无论如何它在这种情况下并没有真正的帮助。索引查找(包括对其他 DBMS 的索引扫描)往往对查找少量行很有帮助。

索引可能用于排序的可能性很小,但我对此表示怀疑。

如果您查看EXPLAIN ANALYZE VERBOSE 的输出,您可以看到排序是在内存中完成的,还是(由于结果的大小)是在磁盘上完成的。

如果排序是在磁盘上完成的,您可以通过增加 work_mem 来加快查询速度 - 无论是全局还是仅针对您的会话。

【讨论】:

  • 谢谢,这是非常有用的信息;这是一个由大量受众执行的公共查询,因此我不确定增加 work_mem 是否是一个好的选择,你怎么看?
  • 如果您有很多连接,则全局增加 work_mem 可能不是一个好主意。但是您可以只为那条语句增加它(使用SET work_mem = ...)。但是您应该首先检查排序是否确实在磁盘上完成
  • 感谢您的宝贵帮助。排序确实在磁盘Sort Method: external merge Disk: 4984kB 上完成;但是,在SET work_mem = '6000' 之后,查询似乎和以前一样长,8 秒,这是不可接受的:-(...
  • @Andre:你设置work_mem后检查计划了吗?默认值为 16MB,因此使用 work_mem = '6000' 您实际上减少了它。也许它需要的不仅仅是日志文件中显示的内容。您应该尝试使用work_mem = '20MB' 之类的方法来超越默认设置。
  • 你是对的(我被postgresql.org/docs/8.2/static/runtime-config-resource.html误导,声明默认值为1MB)在将其设置为20MB之后,查询时间实际上减少了一点(虽然还不够);谢谢,你帮了很多忙! :)
【解决方案2】:

由于field_x 是您的查询中引用的唯一列,因此您的索引covers 应该可以帮助您避免查找myTable 的实际行。

编辑:正如下面的评论讨论中所指出的,虽然这个答案对大多数 RDBMS 实现都有效,但它不适用于 postgresql。

【讨论】:

  • @Joe Stefanelli,谢谢; (更新后)我问这个问题是因为在创建索引之前和之后的查询时间之间没有任何相关差异;它们总是需要大约 8 秒(这当然是太多的时间了!)。这是预期的行为吗?
  • @andre matos:你知道索引存在时是否正在使用吗? EXPLAIN 的输出显示了什么?
  • @Joe:不幸的是,Postgres(还)没有仅索引扫描。在 Postgres 中总是需要“查表”
  • @a_horse:感谢您的洞察力。
  • @Joe Stefanelli,GroupAggregate(成本=46675.90..52671.15 行=299620 宽度=7)-> Sort (cost=46675.90..47425.90 rows=300000 width=7) 排序键:field_x | -> Seq Scan on mytable (cost=0.00..15282.00 rows=300000 width=7)
【解决方案3】:

应该使用索引。如果您想查看索引是如何使用(或不使用)的,查询的执行计划是查看数据库决定做什么的好地方。在您的情况下,您应该执行以下操作:

explain SELECT COUNT(field_x), field_x FROM myTable GROUP BY field_x ORDER BY field_x;

有关您看到的所有输出的更多信息,请参阅 postgres 文档:http://www.postgresql.org/docs/8.4/static/sql-explain.html

还有:http://wiki.postgresql.org/wiki/Image:Explaining_EXPLAIN.pdf,更深入一点。

【讨论】:

  • 感谢您的建议。主要是链接,因为我从来没有真正理解过EXPLAIN 输出...
猜你喜欢
  • 2015-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 1970-01-01
相关资源
最近更新 更多