We recently discovered a performance problem with one of our systems and I think I have the fix but I'm not certain my understanding is correct.
In simplest form, we have a table blah
into which we accumulate various values based on a key field. The basic form is:
recdate date
rectime time
system varchar(20)
count integer
accum1 integer
accum2 integer
There are a lot more accumulators than that but they're all of the same form. The primary key is made up of recdate
, rectime
and system
.
As values are collected to the table, the count for a given recdate/rectime/system
is incremented and the values for that key are added to the accumulators. That means the averages can be obtained by using accumN / count
.
Now we also have a view over that table specified as follows:
create view blah_v (
recdate, rectime, system, count,
accum1,
accum2
) as select distinct
recdate, rectime, system, count,
value (case when count > 0 then accum1 / count end, 0),
value (case when count > 0 then accum2 / count end, 0)
from blah;
In other words, the view gives us the average value of the accumulators rather than the sums. It also makes sure we don't get a divide-by-zero in those cases where the count is zero (these records do exist and we are not allowed to remove them so don't bother telling me they're rubbish - you're preaching to the choir).
We've noticed that the time difference between doing:
select distinct recdate from XX
varies greatly depending on whether we use the table or the view. I'm talking about the difference being 1 second for the table and 27 seconds for the view (with 100K rows).
We actually tracked it back to the select distinct
. What seems to be happening is that the DBMS is actually loading all the rows in and sorting them so as to remove duplicates. That's fair enough, it's what we stupidly told it to do.
But I'm pretty sure the fact that the view includes every component of the primary key means that it's impossible to have duplicates anyway. We've validated the problem since, if we create another view without the distinct, it performs at the same speed as the underlying table.
I just wanted to confirm my understanding that a select distinct
can not have duplicates if it includes all the primary key components. If that's so, then we can simply change the view appropriately.
The SELECT DISTINCT statement is used to return only distinct (different) values. Inside a table, a column often contains many duplicate values; and sometimes you only want to list the different (distinct) values.
As a general rule, SELECT DISTINCT incurs a fair amount of overhead for the query. Hence, you should avoid it or use it sparingly. The idea of generating duplicate rows using JOIN just to remove them with SELECT DISTINCT is rather reminiscent of Sisyphus pushing a rock up a hill, only to have it roll back down again.
The DISTINCT clause is used in the SELECT statement to filter out duplicate rows in the result set. You can use DISTINCT when you select a single column, or when you select multiple columns as we did in our example.
SELECT * will select all the columns from the tables in the FROM clause; SELECT DISTINCT * will find all unique combinations of row data for tables in the FROM clause. DISTINCT forces a sort and unique filtering operations making it far slower for large data.
We can use select with a distinct statement to retrieve unique records from the table. Name of column1 to the name of column N – This is the table column that was used with distinct keywords to retrieve data from a table.
In this case the DISTINCT isn't doing you any good because your distinct fields are already guaranteed to be unique because of the PRIMARY KEY constraint on the underlying table. You might try rewriting the view as:
create view blah_v (
recdate, rectime, system, count,
accum1,
accum2
) as select
recdate, rectime, system, count,
case when count > 0 then accum1 / count else 0 end,
case when count > 0 then accum2 / count else 0 end,
from blah;
Share and enjoy.
Yes, there's no point in asking for distinct
results when all the primary key elements are included.
The table's primary key constraint already precludes duplicates across those columns, but your DBMS will still process the tuples to ensure they are distinct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With