从未使用过外键索引,您可以在pg_stat_user_indexes表中看到。我想删除它们。由于不使用而删除外键索引是否有任何缺点。
db=# SELECT * FROM pg_stat_user_indexes WHERE relname='order_cancellationreason';
relid | indexrelid | schemaname | relname | indexrelname | idx_scan | idx_tup_read | idx_tup_fetch
-------+------------+------------+--------------------------+---------------------------------------------+----------+--------------+---------------
29835 | 31055 | public | order_cancellationreason | order_cancellationreason_address_id | 0 | 0 | 0
29835 | 31053 | public | order_cancellationreason | order_cancellationreason_cancelled_by_id | 0 | 0 | 0
db=#\d+ order_cancellationreason
...
Indexes:
"order_cancellationreason_cancelled_by_id" btree (cancelled_by_id)
"order_cancellationreason_address_id" btree (address_id)
Foreign-key constraints:
"cargo_id_refs_id_f4ffe34d" FOREIGN KEY (cargo_id) REFERENCES cargo_cargoinfo(id) DEFERRABLE INITIALLY DEFERRED
"order_cancellationreason_address_id_fkey" FOREIGN KEY (address_id) REFERENCES invoice_address(id) DEFERRABLE INITIALLY DEFERRED
"order_cancellationreason_cancelled_by_id_fkey" FOREIGN KEY (cancelled_by_id) REFERENCES auth_user(id) DEFERRABLE INITIALLY DEFERRED
答案 0 :(得分:2)
引用外键列的索引不是引用完整性实施所必需的。您只需要在引用列上使用唯一索引。
删除引用列上的索引的唯一缺点是检查和执行可能非常慢。如果您尝试从FK目标表中删除一行,则数据库必须检查该值是否出现在引用列中,并拒绝删除,或者对于ON DELETE CASCADE
键,将其删除。无论哪种方式,如果没有引用列的索引,这可能会导致seqscan。对于那些很好的小型推荐表,但对于一个很大的参考表,尤其是在进行多次FK检查的情况下,性能可能非常糟糕。
如果您的应用程序实际上没有使用FK检查,即他们在那里声明数据模型并且安心,而不是期望它们实际上将被检查和强制执行,那么删除引用列指数可能没问题。
如果你的应用实际上对引用的表执行删除或更新,我建议保留索引。
我尚未确认FK强制执行检查是否正确显示在pg_stat_user_indexes
中。我建议你自己检查一下;尝试运行一些你知道在引用表上失败的删除,并查看引用列上的索引统计信息是否发生变化。