【问题标题】:PostgreSQL text range scanPostgreSQL 文本范围扫描
【发布时间】:2014-05-18 20:54:02
【问题描述】:

我编写了一个查询,其目的是获得 10 个结果,包括当前结果,在任一侧填充最多 9 个条目,以获得可由接收者排序的字母列表。 这是我正在使用的查询,但我的问题不在于结果,而是因为这两个查询都没有使用索引

(
  SELECT
    uid,
    title
  FROM
    books
  WHERE
  lower(title) < lower('Frankenstein')
  ORDER BY title desc
  LIMIT 9
)
UNION
(
  SELECT
    uid,
    title
  FROM
    books
  WHERE
  lower(title) >= lower('Frankenstein')
  ORDER BY title
  LIMIT 10
)
ORDER BY title;

我尝试使用的索引是一个简单的 btree,没有 text_pattern_ops 等如下:

CREATE INDEX books_title_idx ON books USING btree (lower(title));

如果我在联合的第一部分运行解释,尽管有限制和顺序,它会执行全表扫描

explain analyze 
SELECT
  uid,
  title
FROM
  books
WHERE
lower(title) < lower('Frankenstein')
ORDER BY title desc
LIMIT 9

Limit (cost=69.04..69.06 rows=9 width=152) (actual time=6.276..6.292 rows=9 loops=1) -> Sort (cost=69.04..69.67 rows=251 width=152) (actual time=6.273..6.277 rows=9 loops=1) Sort Key: ((title)) Sort Method: top-N heapsort Memory: 25kB -> Seq Scan on books (cost=0.00..63.80 rows=251 width=152) (actual time=0.056..5.227 rows=267 loops=1) Filter: (lower((title)) < 'frankenstein'::text) Rows Removed by Filter: 486 Total runtime: 6.359 ms

当我对同一个查询进行相等性检查时 - 使用了索引

explain analyze
SELECT
  uid,
  title
FROM
  books
WHERE
lower(title) = lower('Frankenstein')
ORDER BY title desc

Sort (cost=17.04..17.05 rows=4 width=152) (actual time=0.054..0.054 rows=0 loops=1) Sort Key: ((title)) Sort Method: quicksort Memory: 25kB -> Bitmap Heap Scan on books (cost=4.31..17.00 rows=4 width=152) (actual time=0.041..0.041 rows=0 loops=1) Recheck Cond: (lower((title)) = 'frankenstein'::text) -> Bitmap Index Scan on books_title_idx (cost=0.00..4.31 rows=4 width=0) (actual time=0.036..0.036 rows=0 loops=1) Index Cond: (lower((title)) = 'frankenstein'::text) Total runtime: 0.129 ms

当我在查询之间进行查询时也是如此

explain analyze
SELECT
  uid,
  title
FROM
  books
WHERE
lower(title) > lower('Frankenstein') AND lower(title) < lower('Gulliver''s Travels')
ORDER BY title

Sort (cost=17.08..17.09 rows=4 width=152) (actual time=0.511..0.529 rows=25 loops=1) Sort Key: (title) Sort Method: quicksort Memory: 27kB -> Bitmap Heap Scan on books (cost=4.33..17.04 rows=4 width=152) (actual time=0.118..0.213 rows=25 loops=1) Recheck Cond: ((lower(title) > 'frankenstein'::text) AND (lower(title) < 'gulliver''s travels'::text)) -> Bitmap Index Scan on books_title_idx (cost=0.00..4.33 rows=4 width=0) (actual time=0.087..0.087 rows=25 loops=1) Index Cond: ((lower(title) > 'frankenstein'::text) AND (lower(title) < 'gulliver''s travels'::text)) Total runtime: 0.621 ms

我显然在这里寻找的不是中间搜索,因为开始和结束是未知的。 那么这是 postgresql 的限制,还是除了将表扫描的成本操纵为一些愚蠢的东西之外,我可以用来说服查询计划者使用索引吗?

我使用的是 PostgreSQL 9.3

【问题讨论】:

    标签: sql database postgresql indexing postgresql-9.3


    【解决方案1】:

    用途:

    ORDER BY <b>lower(</b>title<b>)</b> DESC

    ORDER BY <b>lower(</b>title<b>)</b>

    匹配您的功能索引,以便可以使用它。
    ORDER BY 与其他两个查询中的选择行无关。这就是为什么在这些情况下可以使用索引的原因。

    【讨论】:

    • 我的话,当你看到它时,它是如此明显。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多