Last week I played with queries from TPC-H benchmarks, particularly comparing MySQL 6.0.4-alpha with 5.1. MySQL 6.0 is interesting here, as there is a lot of new changes in optimizer, which should affect execution plan of TPC-H queries. In reality only two queries (from 22) have significantly better execution time (about them in next posts), but I want to write about is queries that execute slower in new MySQL 6.0 version.

Query is pretty simple

with execution plain (in 5.1)

against table

So this query takes 32.27 sec to execute in 5.1, and 39.39 sec in 6.0 (after warpm-ups and fully cached in key_cache)

What is difference in 6.0? Here is execution plain for 6.0:

See there are new Extra notes
USING INDEX condition; USING MRR.

It would be interesting to know what is ‘Using Index condition’, what I was able to find is Baron’s bug with no mention in MySQL 6.0 manual. No mentions about Using MRR also, but I guess it is Multi-Range-Read feature which allows to read data not row-by-row but in batches reads.

So let us see how perform 5.1 and 6.0 in cold mode (I dropped OS caches by

and restarting mysqld)

5.1 – time 1 hour 14 min 36.90 sec
6.0 – time 1 hour 6 min 2.21 sec

So difference is not so big we could speak about big improvements with using MRR here.

What is interesting is iostat -dx 5 output during query execution.

For 5.1 I had:

almost all time. As you see 1285 rkB/s is pretty small for RAID 10 system we have on this server. This is because of Random I/O we had during execution of query, as MySQL used index to scan rows and then did access to data to read other columns.

But for 6 picture is a bit different. At start I had:

and then rkB/s was continuously dropped to

at the end of query execution. I guess we had 4300 rkB/s because of MRR, but I have no idea why this number was dropped to 1200 finally. Probably we need to check how really MRR works.

What else worth to mention here is that MySQL is wrong choosing index scan here. If we try to execute query with IGNORE KEY (li_shp_dt_idx) (full table scan will be performed in this case) then we got:
1 min 39.14 sec to execute query (compare with 1 hour 14 min 36.90 sec).

and iostat here is:

As you see we have sequential I/O with 65362 rkB/s (compare 1200 rkB/s with random I/O), that allows to execute query ~40 times faster.

15 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Peter Zaitsev

The fact optimizer is unaware of caching and fragmentation is one of the most serious practical deficiencies.

Another challenge around the corner for the optimizer is completely different costs for SSD storage compared to standard hard drives.

Jay Pipes

What about putting an index on (quantity, discount, ship_date)?

Sergey Petrunia

Documentation for Index Condition Pushdown and MRR are on our todo.

You can turn index condition pushdown off with this statement:

SET engine_condition_pushdown = off;

and MRR with this statement:

SET optimizer_use_mrr=’disable’;

It would be interesting to see how the first query’s speed is affected by disabling index condition pushdown. Peter, could you do a re-run with after “SET engine_condition_pushdown = off;” ?

Sergey Petrunia

Vadim,

thanks for the answer. So it’s not Index Condition Pushdown (which was our first guess). Would it be too much to ask to re-run with

SET engine_condition_pushdown=off; SET optimizer_use_mrr=’disable’;

so we know if the slowdown is caused by MRR or something else?

Sergey Petrunia

Sure. The idea behind MRR (which stands for Multi Range Read) is to perform range scan as follows:
* Scan the index, collect the rowids in a buffer (of @@read_rnd_buff_size bytes)
* Sort the rowids
* Go and retrieve full table records in one sequential ‘sweep’.

the expected improvement is that the full records are read sequentially which is faster than doing random disk probing. MRR doesn’t provide any speedup when all record data is in disk cache, but it was not expected to cause so much slowdown either.

Timour

Vadim,

Could it be possible that data on disk is already in the right physical order for this query? If the rows in lineitem are already ordered physically roughly in the same order as we would get by ordering the rowids we got via li_shp_dt_idx, then the overhead of MRR could be due to the unnecessary (in this case) rowid sorting.

Could you have a look at the script that populates lineitem and see whether that is the case?

Noah

Hi Vadim,

– Which scale factor are you using?
– How MySQL 5.1/6.0 scales with TPC-H (e.g.: scale factors 1,3,5,10,30,100)?

Thanks,

Noah

Piotr Kołaczkowski

The main cost of executing wide index range scans is NOT the order of the blocks in the table. The main cost is that the blocks are in different places in the table, so even reading them in sequential order still requires to move the disk drive’s heads from place to place. As I first read about MRR and expectations this technique should provide the same speed advantage as clustered indexes, I laughed 😉 Actually MRR would help a little only because MySQL doesn’t take advantage from asynchronous I/O support (or am I wrong?). Having async I/O makes MRR useless, as the OS / disk drive’s firmware does block ordering itself.

martin kersten

Is there a comprehensive list with the TPC-H performance figures for SF-1 until SF-100 for out of the box MySQL, or with all trickery of a DBA applied.