Reputation: 53
I have the following query that was given to me, where the returned record is removed from the table et_fact_reclam_ter_his_misc when the condition is met:
DELETE FROM et_fact_reclam_ter_his_misc
WHERE num_siniest || num_exped IN
(SELECT DISTINCT num_siniest || num_exped
FROM et_fact_reclam_ter_his_misc t1
WHERE NOT EXISTS (SELECT *
FROM et_fact_reclam_ter_misc t2
WHERE t1.num_siniest = t2.num_siniest));
I've been searching, and found that using EXISTS
instead of IN
will improve query performance. But I have run into 2 errors. The first is an error message that appears when I replace the IN
operator with EXISTS
:
DELETE FROM et_fact_reclam_ter_his_misc
WHERE num_siniest || num_exped EXISTS
(SELECT DISTINCT num_siniest || num_exped
FROM et_fact_reclam_ter_his_misc t1
WHERE NOT EXISTS (SELECT *
FROM et_fact_reclam_ter_misc t2
WHERE t1.num_siniest = t2.num_siniest));
ORA-00920: invalid relational operator
The second is when I try to nest a SELECT
inside the DELETE
, but the number of rows returned are different:
DELETE FROM et_fact_reclam_ter_his_misc
WHERE EXISTS
(SELECT FROM et_fact_reclam_ter_his_misc
WHERE num_siniest || num_exped IN
(SELECT DISTINCT num_siniest || num_exped
FROM et_fact_reclam_ter_his_misc t1
WHERE NOT EXISTS
(SELECT *
FROM et_fact_reclam_ter_misc t2
WHERE t1.num_siniest = t2.num_siniest)));
I appreciate any help to improve query performance
Upvotes: 0
Views: 266
Reputation: 15991
Looks like this might do it:
delete et_fact_reclam_ter_his_misc t1
where not exists
( select * from et_fact_reclam_ter_misc t2
where t2.num_siniest = t1.num_siniest
);
In the original version, the first level subquery seems to be querying the same table that is being deleted, just in order to construct a not exists
subquery. I suspect that all you want to do is delete his
rows where num_siniest
does not exist in the main table. Some sample data and expected results would make this clearer.
Upvotes: 0
Reputation: 1552
Could you try below, not the best approach to concatenate fields for joins,
DELETE FROM et_fact_reclam_ter_his_misc A
WHERE EXISTS
( SELECT 1 FROM
(SELECT DISTINCT num_siniest || num_exped
FROM et_fact_reclam_ter_his_misc t1) B
WHERE A.num_siniest|| A.num_exped = B.num_siniest || B.num_exped
AND NOT EXISTS (SELECT 1
FROM et_fact_reclam_ter_misc t2
WHERE B.num_siniest = t2.num_siniest));
Seems like the concatenated columns are numbers and it would force oracle to cast it to char which could hinder performance.Below one should be faster if you are dealing with lots of records.
DELETE FROM et_fact_reclam_ter_his_misc A
WHERE EXISTS
( SELECT 1 FROM
(SELECT DISTINCT num_siniest, num_exped
FROM et_fact_reclam_ter_his_misc t1) B
WHERE A.num_siniest = B.num_siniest
AND A.num_exped = B.num_exped
AND NOT EXISTS (SELECT 1
FROM et_fact_reclam_ter_misc t2
WHERE B.num_siniest = t2.num_siniest));
DISTINCT will overkill, substituting with group by will definitely be far better, so the best one will be :
DELETE FROM et_fact_reclam_ter_his_misc A
WHERE EXISTS
( SELECT 1 FROM
(SELECT num_siniest, num_exped,count(1)
FROM et_fact_reclam_ter_his_misc t1
group by num_siniest, num_exped) B
WHERE A.num_siniest = B.num_siniest
AND A.num_exped = B.num_exped
AND NOT EXISTS (SELECT 1
FROM et_fact_reclam_ter_misc t2
WHERE B.num_siniest = t2.num_siniest));
Upvotes: 1