I have a similar job which compares two large tables (26 mio rows each). I don't need to know which column is different, but if I rephrase the query to do that, it would be something along the lines of
CREATE TABLE t1 (
id NUMBER PRIMARY KEY,
a NUMBER NOT NULL,
b NUMBER NOT NULL,
c NUMBER NULL
);
CREATE TABLE t2 (
id NUMBER PRIMARY KEY,
x NUMBER NOT NULL,
y NUMBER NOT NULL,
z NUMBER NULL
);
INSERT INTO t1 VALUES (1, 10, 20, 30);
INSERT INTO t2 VALUES (1, 10, 20, 30);
INSERT INTO t1 VALUES (2, 10, 20, 30);
INSERT INTO t2 VALUES (2, 11, 20, 30);
INSERT INTO t1 VALUES (3, 10, 21, 30);
INSERT INTO t2 VALUES (3, 10, 20, 30);
INSERT INTO t1 VALUES (4, 10, 20, 31);
INSERT INTO t2 VALUES (4, 10, 20, 30);
INSERT INTO t1 VALUES (5, 10, 20, null);
INSERT INTO t2 VALUES (5, 10, 20, 30);
SELECT id,
CASE WHEN a <> x THEN 1 ELSE 0 END a_x,
CASE WHEN b <> y THEN 1 ELSE 0 END b_y,
CASE WHEN c <> z
OR (c IS NULL AND z IS NOT NULL)
OR (c IS NOT NULL AND z IS NULL) THEN 1 ELSE 0 END c_z
FROM t1 JOIN t2 USING (id)
WHERE a <> x
OR b <> y
OR c <> z OR (c IS NULL AND z IS NOT NULL)
OR (c IS NOT NULL AND z IS NULL);
ID A_X B_Y C_Z
2 1 0 0
3 0 1 0
4 0 0 1
5 0 0 1
The code is lengthy, but I got a script that looks at the data dictionary and writes the query.
However, I'm not totally happy with the comparison of the nullable columns. There is a undokumented system function that makes that easier, but I never got it properly working...