Firebird 现可支持哈希连接(hash join),各中大型数据库,哈希连接已成为平常,相对于循环嵌套连接(Nested Loop Join),在数据量较大的情况下,哈希连接性能较好。
由于 Firebird 的sql查询优化器做的不是很好,需要使用者显式的指定是否使用hash join,否则默认就用循环嵌套连接。
在sql语句上可以这样标示,来使用hash join:
1 select * from b_inbound_puton a 2 join b_inbound_detail b on a.inbound_dt_id +0 = b.id +0 3 join b_inbound c on b.inbound_id +0 = c.id +0 4 where c.id = 0
即,在连接的字段上用 +0 来指定hash join。
执行计划:
1 Select Expression 2 -> Filter 3 -> Hash Join (inner) 4 -> Filter 5 -> Hash Join (inner) 6 -> Filter 7 -> Table "B_INBOUND" as "C" Access By ID 8 -> Bitmap 9 -> Index "PK_B_INBOUND" Unique Scan 10 -> Record Buffer (record length: 321) 11 -> Table "B_INBOUND_DETAIL" as "B" Full Scan 12 -> Record Buffer (record length: 313) 13 -> Table "B_INBOUND_PUTON" as "A" Full Scan
PLAN HASH (HASH (C INDEX (PK_B_INBOUND), B NATURAL), A NATURAL)
Note:并不是所有情况都适合hash join,若强行使用哈希连接,有可能效率会更低,还不如嵌套循环连接,因为它要把小表全部装进内存,再扫描大表,可能有索引的情况也不能利用,综合优化来看。
总归优化时多了一种选择考虑。