我有以下查询从交易表和交易明细获取交易。这两个表都有大量条目,所以此查询需要一段时间才能返回结果。避免全表扫描
SELECT * FROM transactions t LEFT JOIN transac_detail tidts ON (tidts.id_transac = t.id);
不过,我因为事实上,甲骨文执行全表扫描两个表,根据解释计划,即使t.id和tidts.id_transac有索引,更担心。
有什么办法可以在不触及表结构的情况下优化它吗?
我有以下查询从交易表和交易明细获取交易。这两个表都有大量条目,所以此查询需要一段时间才能返回结果。避免全表扫描
SELECT * FROM transactions t LEFT JOIN transac_detail tidts ON (tidts.id_transac = t.id);
不过,我因为事实上,甲骨文执行全表扫描两个表,根据解释计划,即使t.id和tidts.id_transac有索引,更担心。
有什么办法可以在不触及表结构的情况下优化它吗?
我不认为这是真的,SQL必须最好与全表扫描服务。在两者之间存在外键的情况下,这确实是最明显的事实,但即使如此,也可能有例外。
我认为关键的问题是这样的:“每个表中的行的比例应该包含在结果集中?”。如果答案是“100%来自每个”,那么你就有了全表扫描(和散列连接)的清晰情况。
但是考虑一下情况,即表A和表B连接在一起,表A包含5行,并且包含100行的表B(父)的外键包含一行。很明显,在这里你需要用B的嵌套循环连接来查找A的完整扫描(表B中的连接列将被索引,因为它必须是主键或唯一键)。
在OP的情况下,虽然看起来你会期望从每个表中返回100%的行。我期望看到对这两个表的完整扫描,并且首先访问带有TRANSACTIONS(可能是较小的表)的散列连接并将其构建到散列表中。这将是最佳的连接方法,我只是在寻找一种情况,即单次散列连接的TRANSACTIONS太大。如果连接溢出到磁盘上,那么这可能是一个性能问题,您必须考虑增加内存分配或等分两个表以减少内存需求。
非常全面的答案,一如既往。 +1 – 2009-10-21 16:32:21
全表扫描不一定是坏的 - 它似乎并不是以任何方式限制结果集,这可能是执行查询的最有效方式。您始终可以通过使用索引提示并确定结果的性能更改来验证此情况。
由于给定的查询返回所有内容,全表扫描实际上可能是达到最终结果的最快方式。由于I/O与CPU时间相比非常昂贵,因此将所有内容拉入内存并进行最终连接可能更有效,而不是在一个表中循环查找索引。
要确定查询是否可能实际上跑得更快,你可以试试下面的方法:
您没有一个WHERE子句,因此甲骨文认为,因为它必须从两个表返回所有记录全表扫描将是最有效的。
如果您要添加一个使用索引的WHERE子句,我想您会发现EXPLAIN PLAN将不再使用全表扫描。
Oracle做什么?散列连接?哈希联接非常快,通常比使用索引的执行计划更快。向我们展示您的解释计划并检查统计数据是否准确。 – tuinstoel 2009-10-21 18:48:43