[MDEV-8077] Add order by clause make query to 100 times longer to execute Created: 2015-04-29 Updated: 2023-11-28 |
|
| Status: | Open |
| Project: | MariaDB Server |
| Component/s: | Optimizer |
| Affects Version/s: | 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 10.10, 10.11 |
| Fix Version/s: | 10.4, 10.5, 10.6, 10.11 |
| Type: | Bug | Priority: | Major |
| Reporter: | Patrick Quentin Armitage | Assignee: | Sergei Petrunia |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | optimizer, order-by-optimization, subquery, verified | ||
| Environment: |
Fedora 22 |
||
| Attachments: |
|
| Description |
|
The query The query returns 94 rows, the table fd_peal has 335154 rows, and the table bert has 335137 rows. The execution plans for the queries are:
The tables are defined as follows:
I would have expected to order by clause to sort the rows returned by the query, whereas, given the amount of time the query is taking it is presumably doing the order by before the query. |
| Comments |
| Comment by Daniel Black [ 2015-04-29 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
How does the following compare:
Having an index on fd_peal.fid and bert.(fid,sid,rung) would help a lot. Can you include SHOW INDEXES FROM bert; SHOW INDEXES FROM fd_peal | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Daniel Black [ 2015-04-29 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Also might be with trying
too | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Patrick Quentin Armitage [ 2015-04-29 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The issue I was attempting to report was that adding the "order by rung" to the query causes the query to take 100 times longer to execute. The query without the order by clause executes in 0.7 seconds, and so indices clearly aren't needed to make the basic query execute in a reasonable time. Why does adding the order by clause, when one would expect it to only have to sort the 94 rows returned, make the query take 70 seconds instead of 0.7 seconds? I reported this because it looked to me as though something strange was happening with the way the query was being executed, and it might benefit other users if this strange behaviour were resolved. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Patrick Quentin Armitage [ 2015-04-29 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Re query: select fd_peal.* from fd_peal join bert on fd_peal.fid =bert.fid where sid is null order by rung; it takes 31 seconds to execute this whether the order by clause is included to not. The output of the show indexes commands is:
I fully appreciate that adding indices would enable the query to execute more sensibly, but the point was that without the "order by rung" clause it executes in a reasonable time, but with the "order by rung" clause it doesn't | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Daniel Black [ 2015-04-29 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Its sorting the entire fd_peal table first hence the delay. Sorting on the result set is a better solution. Can you include your show global variables output? Mainly interested to see what optimizer settings you have. A optimizer feature not yet enabled by default is https://mariadb.com/kb/en/mariadb/histogram-based-statistics . Is it possible to get the table extract fd_peal(fid,rung) and bert(fid,sid) to save us creating a test case
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Patrick Quentin Armitage [ 2015-04-29 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Attachment op.tar.bz2 has been added that includes the output of "show global variabless" and also the two requested outfiles. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2015-05-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
It's easy enough to reproduce, I created a very artificial data set which only meets two conditions – 300,000 rows in each table and 100 rows intersection for the query – and got similar results. Well, maybe it's not 100x slower for me, but 10-60x, depending on luck, but still.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2015-06-16 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Confirm. I wasn't able to observe such a big difference (for me it's 2x - 5x) but the issue seems to be that the optimizer first sorts the table (sorting 300K rows), and then does the join (which leaves ~90 rows). MySQL/MariaDB generally tries to produce the required ordering as soon as possible. I guess, the reasons for this are: It is actually quite difficult to reliably detect the case where fanout of join operation is much less than 1. Even in this case: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2015-06-16 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I don't see a way to fix this soon. ORDER BY ... LIMIT optimization has other shortcomings that need to be fixed first. Still, thanks for reporting this case, it is useful to know what kind of things are observed in production. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2023-01-22 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I cannot reproduce a considerable difference in execution time anymore, but it looks like the logic which psergei described (first sort the big table, then apply the join condition) may still be the case, so I'm updating the affected/fix versions based on this assumption. |