我有一个必须存储数千个场景的数据库(每个场景都有一个unix_timestamp值)。每个场景都有1,800,000个寄存器,这些寄存器以嵌套集结构组织。 通用表结构由:
给出table_skeleton:
- unix_timestamp integer
- lft integer
- rgt integer
- value
通常,我的SELECT将执行特定场景中的所有嵌套值,例如:
SELECT * FROM table_skeleton WHERE unix_timestamp = 123 AND lft >= 10 AND rgt <= 53
所以我将我的表分层划分为日期组中的主/子,例如:
table_skeleton_201303 inherits table_skeleton:
- unix_timestamp integer
- lft integer
- ...
和
table_skeleton_201304 inherits table_skeleton:
- unix_timestamp integer
- lft integer
- ...
并根据我期望的常规搜索为每个孩子创建索引,例如:
Create Index idx_201303
on table_skeleton_201303
using btree(unix_timestamp, lft, rgt)
它改进了检索,但每次选择仍需要大约1分钟。 我想这是因为索引太大而无法加载到内存中所以我试图为每个时间戳创建部分索引,例如:
Create Index idx_201303_1362981600
on table_skeleton_201303
using btree(lft, rgt)
WHERE unix_timestamp = 1362981600
事实上,创建的第二种索引比一般索引要小得多。但是,当我为此前显示的SELECT运行EXPLAIN ANALYZE时,查询解算器会忽略我的新部分索引,并继续使用巨大的旧索引。
有原因吗? 是否有任何新的方法来优化这种类型的巨大嵌套集分层数据库?
答案 0 :(得分:1)
按field_a&gt;过滤表格时x和field_b&gt; y,那么field_a, field_b
的索引(实际上只是可能,取决于分布和具有field_a&gt; x的行的百分比,根据收集的统计数据)仅用于“ field_a&gt; x“,和field_b&gt; y将是一个顺序搜索。
在上面的例子中,可以使用两个索引,每个字段一个,并且每个结果都加入,内部等效于:
SELECT *
FROM table t
JOIN (
SELECT id table field_a > x) ta ON (ta.id = t.id)
JOIN (
SELECT id table field_b > y) tb ON (tb.id = t.id);
您可以从GIST索引中获益,并将您的lft和rgt字段视为点:
CREATE INDEX ON table USING GIST (unix_timestamp, point(lft, rgt));
SELECT * table
WHERE unix_timestamp = 123 AND
point(lft,rgt) <@ box(point(10,'-inf'), point('inf',53));