Workaround!
This is a workaround for a fast check and not a professional solution. It is only working with numerical columns as identifiers, else convert string columns to numeric (count the letters, convert to bytes or the like) if needed, and NULLs are no problem.
First unprofessional workaround: samples
In the end, since the queries took too long on a 1 Mio table to be compared with another with sometimes NULL values in the fields to care for as well, I have taken quite a few samples of chosen row numbers to test the difference of two tables roughly. I did not find any difference, thinking they are identical anyway.
Second a bit more professional workaround: sum() of columns
Though that sample seemed enough, I wanted to be sure, and summing up all numerical columns, I found differences!
SELECT sum(col1), sum(col2) FROM table1
UNION
SELECT sum(col1), sum(col2) FROM table2
Output is like:
sum(col1) |
sum(col2) |
11111345678 |
123456789101234 |
11111123456 |
123456789101234 |
This summing up of columns or the whole table is the fasted check, and it should usually already answer the main question and reveals more if you group the table by interesting attributes.
Checksum
It is a bit like the CHECKSUM solution in MySQL.
Mind: MySQL!!, not Postgresql:
CHECKSUM TABLE original_table, backup_table;
You might find better ways at How can I get a hash of an entire table in postgresql?.
The issue here is that it is just a Hash, information like in my case, when I could see from the sum of the col1 that there must be 0 or NULL values, gets lost.
Next step: find differences
Next step to find the differences is then to sort by col1 in both tables, or to group by - count() on col1 if it is not unique.
You might also know already which attributes might be the problem and check that, in my case, I new that some col1 might be 0. Summing 0 makes no sense, thus counting here, and the sum of the other column proves the difference:
SELECT count(col1), sum(col2) FROM table1 WHERE col1 = 0
UNION
SELECT count(col1), sum(col2) FROM table1 WHERE col1 = 0
count(col1) |
sum(col2) |
1234 |
123456789 |
345 |
6543210 |
A counter-query:
SELECT count(col1), sum(col2) FROM table1 WHERE col1 <> 0
UNION
SELECT count(col1), sum(col2) FROM table1 WHERE col1 <> 0
and after some time, you find the candidates with some luck or after a group by overview that you can check as well by subtracting the one from the other, ORDER BY difference DESC
.
Perhaps run long-running queries now
But even if you know heavy scripts now to find the real differences in a full table check, you know at least that waiting for an hour or more makes sense at all. :)
Small hint: select into a new table
Small hint: if you run such a long-lasting query, consider indexing at first. Also, check whether you might better directly create a table from the sql results using
CREATE TABLE MY_TABLE AS SELECT ...
So that you have the results not just in the output.
EXCEPT
, check this question: An efficient way to compare two large data sets in SQL