range_optimizer_max_mem_size Might Cause Full Table ScanAlthough how range_optimizer_max_mem_size operates is explained in the official doc, it’s not a well-known variable and surely not a variable you need to modify under most circumstances. But from time to time we get some performance tickets related to this.

What problem does this variable cause if it is not properly sized? Let’s find out with an example!

Given the following table definition:

With ~2M rows

With the default value of  range_optimizer_max_mem_size = 8388608, the following query on PK executes very fast!

But what if we decrease range_optimizer_max_mem_size to let’s say, 500?

Woooh! Query execution time increased from 0.00 seconds to 0.82 seconds! What might be happening? Let’s check the explain and handlers:

With range_optimizer_max_mem_size = 8388608:

With range_optimizer_max_mem_size = 500:

It can be seen that there was a query plan execution change. With default value, the execution plan used the primary key to scan only 10 rows, but after decreasing range_optimizer_max_mem_size, a full table scan occurred which resulted in 2097153 row reads! This can be detrimental to performance.

The formal explanation for this behavior can be found at the end of the official documentation.

To estimate the amount of memory needed to process a range expression, you should check the query condition, and in the case of IN() predicate, it will require 230 bytes per value. For completeness, it’s worth knowing that each “OR” condition in the where clause will require an additional 230 bytes, and each “AND” condition an additional 125 bytes.

Having the default value of 8388608 (MySQL version 5.7.12 and above) should be enough for up to an IN condition of ~36473 clauses.

In conclusion, it can be seen that the default value should be more than enough for most (if not all) the queries, but after a tipping point (or if the variable is misconfigured), it might happen that a well-performing query turns into a full table scan that can be detrimental to performance.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Kay Agahd

Interesting insights, thank you!
Do you know if there is an equivalent in MongoDB? I mean, does MongoDB behaves similarly when the IN condition contains many values and does MongoDB also provides a parameter to tune it?