i have a code that works,
CURSOR c_val IS
SELECT 'Percentage' destype,
1 descode
FROM dual
UNION ALL --16028 change from union to union all for better performance
SELECT 'Unit'destype,
2 descode
FROM dual
ORDER BY descode DESC;
--
i change the union to union all, from what i have read it wouldnt make a big differnece as long as i have a order by (which i do) , is this truth or should i just leave it the way it was , it still works both ways
The choice between UNION and UNION ALL is not whether one of them works or not, or whether one of them is faster performing, but which one is correct for the logic you want to implement.
UNION ALL is simply the results of the two queries combined into a single result set. You should consider the order of the result sets to be random, although in practice you'd probably find that it's the first result set followed by the second.
UNION is the same, but with a DISTINCT applied to the combined sets. Therefore it's possible for it to return fewer rows and take longer and consume more resources. You would probably find that the order of rows is different, but again you should assume that the order is random.
Applying an ORDER BY to either one of them is the only way to guarantee an order on the result set. It would affect performance of the UNION ALL, but may not affect UNION too much (on top of the impact of the DISTINCT) because the optimiser might choose a DISTINCT implementation that will return an ordered result set.
So in your case you want both rows to appear (and in fact UNION would not eliminate either of them), and you want the order to be specified -- so based on that, UNION ALL and the ORDER BY you have provided are the correct approaches.
"UNION" = "UNION ALL" + "DISTINCT"
So basically by going for UNION ALL you save a dedup operation. In this case you may find that the performance gain is negligible but it can be important on large datasets.
Union All returns all rows, so you might get duplicates. Union is effectively like a distinct. In your case, it doesn't make a difference as you are using the same tables!
Related
I would like to optimize performance while bringing together queries on many SAS data sets with the same metadata. At this point I have:
select * from
(select t1.column_a, t1.column_b
from table t1)
Union
(select t2.column_a, t2.column_b
from table t2)
and so on.
Each query brings up unique rows, do I save time wise if I use use Union All instead?
Yes. you are correct. Please refer this. What is the difference between UNION and UNION ALL?
If you are pretty sure that you don't have duplicates, then you can just use the UNION ALL instead of UNION. The later lacks in performance as it has to remove the duplicates
At some point during UNION there will be checks for duplicates. Even if these checks all turn up false, they are an extra step. UNION ALL will probably be more efficient but as dfundako pointed out, you'll have to test and see to be sure of a difference in speed.
I am fetching data using Union operator. I want my output to be in the same order as my select queries are fetching but instead Union sorts it in alphabetical order. Can you suggest me a way to avoid getting it sorted by default.
Try to do it in a subquery like this:
select * from (select x , y ,z from table1
UNION ALL
select x,y,z from table2)
order by y
Thilo is correct: to be safe, a query should always explicitly order the results. Relying on implicit sorting has caused many problems in the past and will continue to cause more problems in the future.
The suggestion that UNION ALL will avoid the sorting is almost always correct. It should work in 11g and below. But 12c introduced concurrent execution of union all, which does not guarantee the order of results any more.
Even if implicit sorting works right now it's always a good idea to add an ORDER BY.
You should not rely on the order if you do not specify any ORDER BY clause.
UNION guaranties uniquines of the result. Pre 10g versions used sort to remove duplicates. Newer Oracle version also might (but not must) use a hash-table to remove duplicates - therefore the result is not necessarily sorted.
UNION ALL does not care about uniquines.
You can simply type:
select x , y ,z from table1
UNION ALL
select x,y,z from table2
order by y
Order by applies onto the whole result.
Is it possible for UNION of two sql statements to produce an output that is different from output of executing each of the two statements separately?
Yes. Absolutely.
The union removes duplicates. If you want the same results, use union all.
Also note: the ordering after union and union all is not guaranteed. If you want things in a particular order, use order by.
This question already has answers here:
SQL Server UNION - What is the default ORDER BY Behaviour
(6 answers)
Closed 9 years ago.
Can I be sure that the result set of the following script will always be sorted like this O-R-D-E-R ?
SELECT 'O'
UNION ALL
SELECT 'R'
UNION ALL
SELECT 'D'
UNION ALL
SELECT 'E'
UNION ALL
SELECT 'R'
Can it be proved to sometimes be in a different order?
There is no inherent order, you have to use ORDER BY. For your example you can easily do this by adding a SortOrder to each SELECT. This will then keep the records in the order you want:
SELECT 'O', 1 SortOrder
UNION ALL
SELECT 'R', 2
UNION ALL
SELECT 'D', 3
UNION ALL
SELECT 'E', 4
UNION ALL
SELECT 'R', 5
ORDER BY SortOrder
You cannot guarantee the order unless you specifically provide an order by with the query.
No it does not. SQL tables are inherently unordered. You need to use order by to get things in a desired order.
The issue is not whether it works once when you try it out. The issue is whether you can trust this behavior. And you cannot. SQL Server does not even guarantee the ordering for this:
select *
from (select t.*
from t
order by col1
) t
It says here:
When ORDER BY is used in the definition of a view, inline function,
derived table, or subquery, the clause is used only to determine the
rows returned by the TOP clause. The ORDER BY clause does not
guarantee ordered results when these constructs are queried, unless
ORDER BY is also specified in the query itself.
A fundamental principle of the SQL language is that tables are not ordered. So, although your query might work in many databases, you should use the version suggested by BlueFeet to guarantee the ordering of results.
Try removing all of the ALLs, for example. Or even just one of them. Now consider that the type of optimization that has to happen there (and many other types) will also be possible when the SELECT queries are actual queries against tables, and are optimized separately. Without an ORDER BY, ordering within each query will be arbitrary, and you can't guarantee that the queries themselves will be processed in any order.
Saying UNION ALL with no ORDER BY is like saying "Just throw all the marbles on the floor." Maybe every time you throw all the marbles on the floor, they end up being organized by color. That doesn't mean the next time you throw them on the floor they'll behave the same way. The same is true for ordering in SQL Server - if you don't say ORDER BY then SQL Server assumes you don't care about order. You may see by coincidence a certain order being returned all the time, but many things can affect the arbitrary order that has been selected next time. Data changes, statistics changes, recompile, plan flush, upgrade, service pack, hotfix, trace flag... ad nauseum.
I will put this in large letters to make it clear:
You cannot guarantee an order without ORDER BY
Some further reading:
Bad habits to kick : relying on undocumented behavior
Also, please read this post by Conor Cunningham, a pretty smart guy on the SQL team.
No. You get the records in whatever way SQL Server fetches them for you. You can apply an order on a unioned result set by 1-based index thusly:
SELECT 1, 'O'
UNION ALL
SELECT 2, 'R'
UNION ALL
SELECT 3, 'D'
UNION ALL
SELECT 4, 'E'
UNION ALL
SELECT 5, 'R'
ORDER BY 1
I need help on performance of a query I have that is very slow.
The query is doing a case on a column in order to return a different text value
based on the number.
If I had a table with values 1-5 and 8-10 If something has a value of 1 it should display 'Apple' or if it is 2 it must display 'pear' if it is anything other than 1-5 then it is 'other'. Currently a case statement is being used, but I heard that functions on a query makes it slower.
All I want is the 'Wording' to appear instead of the the number but because the table is so big it feels to me like it is iterating each row just to determine what to display.
Is there a faster way of doing this.I considered doing a join, which seems like it would work nice, but I dont know how to write 'other' for anything other than 1-5
A case statement is not a function. User-defined functions do have additional overhead in some versions of SQL. You don't, as a general rule, need to worry about the overhead for built-in functions.
You could do this with a join as:
with lookup as (
select 1 as val, 'Apple' as str union all
select 2 as val, 'Pear' as str union all
select 3 union all select 4 union all select 5
)
select coalesce(l.val, 'other')
from t left outer join
lookup l
on t.col = l.val
I would expect the case statement to be marginally faster though.