Say I have a sequence of queries that progressively get more expensive. I can join all these with a union but I'm only interested in the top 10 results so I add a LIMIT. The query looks something like this:
(SELECT col1, col2 FROM table WHERE colx = 'x')
UNION
(SELECT col1, col2 FROM table WHERE colx LIKE '%x%')
UNION
(SELECT col1, col2 FROM table WHERE colx LIKE '%x%' AND unindexedcol LIKE '%y%')
LIMIT 10
I know that this is not guaranteed to be the top 10 from the first query as the MySQL documentation states
UNION by default produces an unordered set of rows
but in practice it appears that the results are ordered select 1 followed by select 2 etc until the limit is reached.
So does MySQL execute the queries sequentially and stop when it hits the limit? If not then what is a better way to execute this style of query where only a subset of results are needed and prioritisation of less expensive queries is preferred to minimize execution time?
19, you can use ORDER BY and LIMIT with TABLE in unions in the same way as just shown, bearing in mind that TABLE does not support a WHERE clause. This kind of ORDER BY cannot use column references that include a table name (that is, names in tbl_name .
UNION ALL is faster than UNION because plain UNION is expecting that within two joined datasets are duplicates which need to be removed. If you can ensure (by inner WHERE clauses) that there will be no duplicates, it's far better to use UNION ALL and let database engine optimize the inner selects.
You need to start Googling. Select * from ( select things from tables where condition 1 AND condition 2 AND condition 3 union select things from different_tables where condition 4 AND condition 5 ) -> That's the most optimized approach, given the information provided.
A UNION statement effectively does a SELECT DISTINCT on the results set. If you know that all the records returned are unique from your union, use UNION ALL instead, it gives faster results.
I have made a test to demonstrate MySQL does not optimize that kind of query: First of all I execute this query:
select @a1 := 0;
select @a2 := 0;
(SELECT id, @a1:=@a1+1 FROM companies)
UNION
(SELECT id, @a2:=@a2+1 FROM invoices)
LIMIT 10;
Then I watch the values of @a1 and @a2 variables:
select @a1 as a1, @a2 as a2;
In my tests they are a1 = 81 and a2 = 467. So the single selects of union query are not limited.
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