【发布时间】:2020-09-29 11:27:34
【问题描述】:
我正在寻找一个索引来快速完成以下操作:
CREATE TABLE mytable (
t1 INT NOT NULL,
t2 INT NOT NULL,
latest_creation_date INT NOT NULL,
data_category_id CHAR(36) NOT NULL,
value VARCHAR(255) NOT NULL,
PRIMARY KEY(latest_creation_date, t1, t2, data_category_id))
查询是删除,内容如下:
delete
from mytable
where
latest_creation_date = 0
and Not (
(t1 = 5 and t2 = 10)
or (t1 = 15 and t2 = 20)
or (t1 = 215 and t2 = 320)
or (t1 = 315 and t2 = 420)
...
or (t1 = 415 and t2 = 520)
or (t1 = 515 and t2 = 620));
所以它会删除所有与 t1 和 t2 上的几百个条件不匹配的行。
explain 进行顺序扫描并重新排列查询:
Delete on mytable (cost=0.00..2517652.30 rows=38182950 width=6)
-> Seq Scan on mytable (cost=0.00..2517652.30 rows=38182950 width=6)
Filter: ((latest_creation_date = 0) AND ((t1 <> 5) OR (t2 <> 10)) AND ((t1 <> 15) OR (t2 <> 20)) AND ((t1 <> 215) OR (t2 <> 320)) AND ((t1 <> 315) OR (t2 <> 420)) AND ((t1 <> 415) OR (t2 <> 520)) AND ((t1 <> 515) OR (t2 <> 620)))
我可以创建一个可以避免全扫描的索引吗?
提前致谢!
【问题讨论】:
-
这样的索引应该是可能的postgresql.org/docs/8.0/indexes-partial.html
-
即使您在 t1 和 t2 上添加索引,查询优化器也可能会选择扫描以删除 大部分 行
-
嗯,值正在改变,@AntonínLejsek,我希望使用主键。但我认为这是不可能的,因为
<>比较。 -
您可能可以通过设置
enable_seqscan = off让它使用现有索引,但这实际上可能不会更快。
标签: sql postgresql indexing