我需要从table1
中删除table2
中存在的ID的数据。
我已经执行了以下语句,但即使存在索引,也会进行表扫描:
DELETE FROM table1 t1 WHERE t1.ID IN (SELECT T.ID FROM table2 T) ;
是否有其他方法可以在DB2中为delete语句连接表,以便我可以避免表扫描。
答案 0 :(得分:3)
表格扫描本身并不一定是坏事。
CAVEAT :如果没有针对table1
的解释计划或DDL,则无法为此特定案例获得完整答案。
也就是说,DB2的优化器将确定执行查询的最有效计划。根据您从table1
删除的数据量,扫描表可能比通过索引删除每个ID然后获取行更有效。
优化器决定的一些因素是:
表和索引统计
要删除的行数(以及相对于table1
中的总行数)
可能有用的索引的群集比率(或群集因子)
上述索引中的级别数
缓冲池大小
这是一个非常简单的例子,说明表扫描不一定是坏的:
假设t1
有500页,而您认为应该使用的索引i1
有3个级别和非常低的集群因子。此外,我们假设您要从表中删除200 行。
要通过简单的表扫描执行删除,DB2将扫描表的500个数据页。
要通过索引进行删除,对于要删除的每一行,它将读取3个索引页(根页,中间页和叶页),以及保存该行的数据页。 (每个要删除的行读取4个数据页)。因此,当删除200行时,使用索引意味着DB2正在读取800页(比表扫描多60%) - 因此优化器选择表扫描。
显然它比这复杂得多 - 索引的大小,无论是进行完整的索引扫描还是(如上所述)逐步执行每行的索引,缓冲池大小,群集比率等等都会影响到优化者的决定。但是在很多情况下,表扫描确实是给定查询的最有效方法。