Firebird中选择查询的性能问题

时间:2012-06-27 18:17:40

标签: sql database performance optimization firebird2.5

我有两个表,一个小(约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字段,这是它的主键。 查询计划显示外键索引用于large_table:

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

已重新计算两个表的索引的统计数据。

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

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

2 个答案:

答案 0 :(得分:0)

我不确定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查询。

答案 1 :(得分:0)

如果大表只有little_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

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