删除未使用的外键索引的缺点?

时间:2013-02-21 15:06:08

标签: postgresql indexing foreign-keys

从未使用过外键索引,您可以在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

1 个答案:

答案 0 :(得分:2)

引用外键列的索引不是引用完整性实施所必需的。您只需要在引用列上使用唯一索引。

删除引用列上的索引的唯一缺点是检查和执行可能非常慢。如果您尝试从FK目标表中删除一行,则数据库必须检查该值是否出现在引用列中,并拒绝删除,或者对于ON DELETE CASCADE键,将其删除。无论哪种方式,如果没有引用列的索引,这可能会导致seqscan。对于那些很好的小型推荐表,但对于一个很大的参考表,尤其是在进行多次FK检查的情况下,性能可能非常糟糕。

如果您的应用程序实际上没有使用FK检查,即他们在那里声明数据模型并且安心,而不是期望它们实际上将被检查和强制执行,那么删除引用列指数可能没问题。

如果你的应用实际上对引用的表执行删除或更新,我建议保留索引。

我尚未确认FK强制执行检查是否正确显示在pg_stat_user_indexes中。我建议你自己检查一下;尝试运行一些你知道在引用表上失败的删除,并查看引用列上的索引统计信息是否发生变化。