SQL Performance UNION vs OR
Either the article you read used a bad example, or you misinterpreted their point.
select username from users where company = 'bbc' or company = 'itv';
This is equivalent to:
select username from users where company IN ('bbc', 'itv');
MySQL can use an index on company
for this query just fine. There's no need to do any UNION.
The more tricky case is where you have an OR
condition that involves two different columns.
select username from users where company = 'bbc' or city = 'London';
Suppose there's an index on company
and a separate index on city
. Given that MySQL usually uses only one index per table in a given query, which index should it use? If it uses the index on company
, it would still have to do a table-scan to find rows where city
is London. If it uses the index on city
, it would have to do a table-scan for rows where company
is bbc.
The UNION
solution is for this type of case.
select username from users where company = 'bbc'
union
select username from users where city = 'London';
Now each sub-query can use the index for its search, and the results of the subquery are combined by the UNION
.
An anonymous user proposed an edit to my answer above, but a moderator rejected the edit. It should have been a comment, not an edit. The claim of the proposed edit was that UNION has to sort the result set to eliminate duplicate rows. This makes the query run slower, and the index optimization is therefore a wash.
My response is that that the indexes help to reduce the result set to a small number of rows before the UNION happens. UNION does in fact eliminate duplicates, but to do that it only has to sort the small result set. There might be cases where the WHERE clauses match a significant portion of the table, and sorting during UNION is as expensive as simply doing the table-scan. But it's more common for the result set to be reduced by the indexed searches, so the sorting is much less costly than the table-scan.
The difference depends on the data in the table, and the terms being searched. The only way to determine the best solution for a given query is to try both methods in the MySQL query profiler and compare their performance.
Performance of UNION versus UNION ALL in SQL Server
UNION ALL will perform better than UNION when you're not concerned about eliminating duplicate records because you're avoiding an expensive distinct sort operation. See: SQL SERVER – Difference Between Union vs. Union All – Optimal Performance Comparison
Why is UNION faster than an OR statement
The reason is that using OR
in a query will often cause the Query Optimizer to abandon use of index seeks and revert to scans. If you look at the execution plans for your two queries, you'll most likely see scans where you are using the OR
and seeks where you are using the UNION
. Without seeing your query it's not really possible to give you any ideas on how you might be able to restructure the OR
condition. But you may find that inserting the rows into a temporary table and joining on to it may yield a positive result.
Also, it is generally best to use UNION ALL
rather than UNION
if you want all results, as you remove the cost of row-matching.
Performance of Union as a subquery vs Individual
The first is marginally better, because the filtering happens before the union
. union
removes duplicates, so that incurs overhead.
A better approach is to unpivot the data:
SELECT DISTINCT v.eventname, e.del_flag
FROM event e CROSS APPLY
(VALUES (eventname1), (eventname2), . . .
) v(eventname)
WHERE e.del_flag = 0 AND e.eventname LIKE '%1%';
This is better because it only needs to read the table once, rather twelve times. However, it is still incurring overhead to remove duplicates.
Why using OR condition instead of Union caused a performance Issue
Using UNION ALL
to replace OR
is actually one of the well known optimization tricks. The best reference and explanation is in this article: Index Union.
The gist of it is that OR
predicates that could be be satisfied by two index seeks cannot be reliably detected by the query optimizer (the reason being impossibility to predict the disjoint sets from the two sides of the OR). So when expressing the same condition as an UNION ALL then the optimizer has no problem creating a plan that does two short seeks and unions the results. The important thing is to realize that a=1 or b=2
can be different from a=1 union all b=2
because the first query returns rows that satisfy both conditions once, while the later returns them twice. When you write the query as UNION ALL you are telling the compiler that you understand that and you have no problem with it.
For further reference see How to analyse SQL Server performance.
Use A Union Or A Join - What Is Faster
Union will be faster, as it simply passes the first SELECT statement, and then parses the second SELECT statement and adds the results to the end of the output table.
The Join will go through each row of both tables, finding matches in the other table therefore needing a lot more processing due to searching for matching rows for each and every row.
EDIT
By Union, I mean Union All as it seemed adequate for what you were trying to achieve. Although a normal Union is generally faster then Join.
EDIT 2 (Reply to @seebiscuit 's comment)
I don't agree with him. Technically speaking no matter how good your join is, a "JOIN" is still more expensive than a pure concatenation. I made a blog post to prove it at my blog codePERF[dot]net. Practically speaking they serve 2 completely different purposes and it is more important to ensure your indexing is right and using the right tool for the job.
Technically, I think it can be summed using the following 2 execution plans taken from my blog post:
UNION ALL
Execution Plan
JOIN
Execution Plan
Practical Results
Practically speaking the difference on a clustered index lookup is negligible:
Related Topics
Insert Data in 3 Tables At a Time Using Postgres
Select Count(*) from Multiple Tables
T-Sql: Round to Nearest 15 Minute Interval
SQL Query to Get Aggregated Result in Comma Separators Along With Group by Column in SQL Server
Sql: Creating a Relational Table With 2 Different Auto_Increment
What Is Sysname Data Type in SQL Server
Is There a Group_Concat Function in Ms-Access
Export SQL Query Data to Excel
SQL String Comparison, Greater Than and Less Than Operators
SQL Runs Fast in Ssms Slow in ASP.NET
Why Is There No Product Aggregate Function in SQL
Can a Check Constraint Relate to Another Table
Int VS Unique-Identifier for Id Field in Database
How to Convert an Integer (Time) to Hh:Mm:Ss::00 in SQL Server 2008