我想决定使用citext
带有索引的列或使用text
索引为 on 的列lower()
.
我执行了一些基准测试。令我惊讶的是,索引打开的搜索lower()
导致索引扫描,但在citext
如果我只进行索引扫描。我本来期待索引lower()
也导致仅索引扫描。
此外,总成本citext
指数为 4.44,但指数为lower()
,总成本为8.44。
所以我首先想到的是citext
列索引优于 a 上的表达式索引text
column.
CREATE TABLE test_citext(a citext NOT NULL);
INSERT INTO test_citext
SELECT cast(x as text)
FROM generate_series(1, 1000000) AS x;
VACUUM (FREEZE, ANALYZE) test_citext;
create index citextind on test_citext(a);
Select * from test_citext where a = 'test';
--Index Only Scan.Total cost 4.44
CREATE TABLE test_textlowerindex(a text NOT NULL);
INSERT INTO test_textlowerindex
SELECT cast(x as text)
FROM generate_series(1, 1000000) AS x;
VACUUM (FREEZE, ANALYZE) test_textlowerindex;
create index lowertextind on test_textlowerindex(lower(a));
Select * from test_textlowerindex where lower(a) = 'test';
--Index Scan.Total cost 8.44
我对吗?
劳伦斯·阿尔贝先生感谢您的回答。我按照您所说的更改了上面的脚本。
结果 :
CREATE TABLE test_citext(a citext NOT NULL);
INSERT INTO test_citext
SELECT cast(x as text)
FROM generate_series(1, 1000000) AS x;
create index citextind on test_citext(a);
VACUUM (FREEZE, ANALYZE) test_citext;
Select count(*) from test_citext where a = 'test';
--Index Only Scan 4.44 + 4.46
CREATE TABLE test_textlowerindex(a text NOT NULL);
INSERT INTO test_textlowerindex
SELECT cast(x as text)
FROM generate_series(1, 1000000) AS x;
create index lowertextind on test_textlowerindex(lower(a));
VACUUM (FREEZE, ANALYZE) test_textlowerindex;
Select count(*) from test_textlowerindex where lower(a) = 'test';
--Index Scan 8.44 + 8.46
但即使我在创建索引并在 select.Index Scan 中使用 count(*) 后运行分析,任何事情都没有改变。Index Scan 仍然继续使用 lower() 上的索引。