我编写了一个查询,其目的是获得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));
如果我在unioin的第一部分运行解释,尽管有限制和顺序,它会执行全表扫描
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
答案 0 :(得分:2)
使用:
ORDER BY lower(title) DESC
或
ORDER BY lower(title)
到匹配您的功能索引,因此可以使用它
ORDER BY
与其他两个查询中的选择行无关。这就是为什么索引可以用于这些情况。