2

我有两张表,一张小(~ 400 行),一张大(~ 1500 万行),我试图从小表中查找在大表中没有关联条目的记录。

我在查询中遇到大量性能问题

查询是:

SELECT * FROM small_table WHERE NOT EXISTS
  (SELECT NULL FROM large_table WHERE large_table.small_id = small_table.id)

该列large_table.small_id引用 small_table 的id字段,这是它的主键。查询计划显示大表使用了外键索引:

PLAN (large_table (RDB$FOREIGN70))
PLAN (small_table NATURAL)

已为两个表上的索引重新计算统计信息。

查询需要几个小时才能运行。这是预期的吗?

  • 如果是这样,我可以重写查询以使其更快吗?
  • 如果没有,可能有什么问题?
4

2 回答 2

1

如果大表只有相对较少的 small_id 不同值,则以下可能会执行得更好:

select *
from small_table st left outer join
     (select distinct small_id
      from large_table
     ) lt
     on lt.small_id = st.id
where lt.small_id is null

在这种情况下,通过对大表进行全面扫描,然后在小表中查找索引,性能会更好——这与它正在做的相反。做一个不同的可以只对大表进行索引扫描,然后使用小表上的主键索引。

于 2012-06-27T21:26:25.330 回答
1

我不确定 Firebird,但在其他数据库中,连接通常更快。

SELECT    *
FROM      small_table st
LEFT JOIN large_table lt
ON        st.id = lt.small_id
WHERE     lt.small_id IS NULL

也许试试看?

另一种选择,如果你真的被卡住了,并且根据需要运行的情况,将 small_id 列从 large_table 中取出,可能放入临时表中,然后执行左连接/EXISTS 查询。

于 2012-06-27T18:40:41.440 回答