我有一个查询从表中删除一些记录,但需要花费太多时间。 该表在存储过程中使用它来匹配另一个表。
每次执行SP时,表都会被截断,并根据收到的参数填充2或3百万条记录。
该表没有任何FK或约束
删除我正在使用的记录的查询是:
DELETE FROM TABLE1
WHERE (fecha,hora_ini,origen,destino,tipo,valor,rowsm1) IN (
SELECT fecha_t,hora_t,origen_t,destino_t,tipo,valor,id_t
FROM TABLE2)
我尝试减少执行查询的时间,该查询基于查询的相同列
创建索引CREATE INDEX smb1 ON table1 (fecha,hora_ini,origen,destino,tipo,valor,rowsm1);
查询需要更多时间才能执行。
如何提高此“DELETE”查询的效果。
更新
EXPLAIN PLAN OUTPUT
DELETE TABLE1
TABLE ACCESS TABLE1
TABLE ACCESS FULL TABLE1
TABLE ACCESS FULL TABLE2
TABLE ACCESS FULL TABLE2
答案 0 :(得分:0)
您创建的索引看起来像一个非常大的索引:
CREATE INDEX smb1
ON table1 (fecha,hora_ini,origen,destino,tipo,valor,rowsm1);
当然,这取决于数据量,但通常我宁愿寻找一两个selective columns - 如果可能的话。
不要忘记,索引数据也必须被读取,如果它无法帮助加快查询速度,您甚至会失去性能。
如果表非常小,这可能会发生,因为数据库逐块读取数据(我认为它大约是8K)。可以一步读取一个小表 - 这里不需要使用索引。
或者,如果选择了更多或更少的所有记录。在这种情况下,无论如何都必须阅读表格。
如果要加快查询速度,则应在table2
上创建相同的索引(具有良好的选择性)。这样EXPLAIN PLAN
看起来有点像这样:
DELETE STATEMENT
DELETE
NESTED LOOPS SEMI
INDEX FULL SCAN
INDEX RANGE SCAN
答案 1 :(得分:-1)
您可以关闭日志记录并删除行
这是一个例子,你可以用2种方式做到,
1。)将表格物理地转换为Nologging
2.。)在删除语句中使用Nologging提示。
1。)第一种方法
testemp和testemp2都是相同数据的表,而testemp需要一分钟,testemp2只需1秒
SQL> delete from testemp;
14336 rows deleted.
Elapsed: 00:01:04.12
SQL>
SQL>
SQL> alter table testemp2 nologging;
Table altered.
Elapsed: 00:00:02.86
SQL>
SQL> delete from testemp2;
14336 rows deleted.
Elapsed: 00:00:01.26
SQL>
只有当我们使用“Alter”命令物理更改表时,才需要将表重新记录到日志中,如果您使用的是不需要的提示,请参阅下面的示例
2.)第二种方法
SQL> set timing on;
SQL> delete from testemp2;
14336 rows deleted.
Elapsed: 00:00:01.51
Deleting data after reinserting same data into table now with nologging;
SQL> delete /*+NOLOGGING*/ from testemp2;
14336 rows deleted.
Elapsed: 00:00:00.28
SQL> select logging from user_Tables where table_name='TESTEMP2';
LOG
---
YES