[wp-trac] [WordPress Trac] #14258: wp_options and MySQL's "log-queries-not-using-indexes" config
WordPress Trac
noreply at wordpress.org
Thu Feb 9 03:12:28 UTC 2017
#14258: wp_options and MySQL's "log-queries-not-using-indexes" config
--------------------------+--------------------------
Reporter: pkirk | Owner:
Type: defect (bug) | Status: reopened
Priority: normal | Milestone:
Component: Database | Version: 4.7.2
Severity: normal | Resolution:
Keywords: | Focuses: performance
--------------------------+--------------------------
Changes (by arjenlentz):
* status: closed => reopened
* type: enhancement => defect (bug)
* version: => 4.7.2
* resolution: wontfix =>
Comment:
Replying to [comment:3 pento]:
> Adding an index won't improve performance for this. If a query going
through an index reads more than 30% of the rows, MySQL will revert to a
table scan.
Sorry pento, but this is not correct. It is a neat rule of thumb that
we've used in training also, but there is no such rule in the code itself.
(feel free to try and prove me wrong, show me a relevant MySQL server
source code snippet - hint: I used to work for MySQL).
What's relevant is the selectivity, and having an index on a boolean can
make a significant difference - more so in more recent versions of MySQL
and MariaDB.
But let's just check this in the real world, as that's what matters:
{{{
> explain SELECT option_name, option_value FROM wp_options WHERE autoload
= 'yes';
+------+-------------+------------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len
| ref | rows | Extra |
+------+-------------+------------+------+---------------+------+---------+------+-------+-------------+
| 1 | SIMPLE | wp_options | ALL | NULL | NULL | NULL
| NULL | 60453 | Using where |
+------+-------------+------------+------+---------------+------+---------+------+-------+-------------+
> ALTER TABLE wp_options ADD INDEX (autoload);
> explain SELECT option_name, option_value FROM wp_options WHERE autoload
= 'no';
+------+-------------+------------+------+---------------+----------+---------+-------+-------+-----------------------+
| id | select_type | table | type | possible_keys | key |
key_len | ref | rows | Extra |
+------+-------------+------------+------+---------------+----------+---------+-------+-------+-----------------------+
| 1 | SIMPLE | wp_options | ref | autoload | autoload | 82
| const | 30228 | Using index condition |
+------+-------------+------------+------+---------------+----------+---------+-------+-------+-----------------------+
1 row in set (0.00 sec)
> explain SELECT option_name, option_value FROM wp_options WHERE autoload
= 'yes';
+------+-------------+------------+------+---------------+----------+---------+-------+------+-----------------------+
| id | select_type | table | type | possible_keys | key |
key_len | ref | rows | Extra |
+------+-------------+------------+------+---------------+----------+---------+-------+------+-----------------------+
| 1 | SIMPLE | wp_options | ref | autoload | autoload | 82
| const | 2329 | Using index condition |
+------+-------------+------------+------+---------------+----------+---------+-------+------+-----------------------+
}}}
As you can see, there is quite a difference with an index, particularly
for the 'yes' case.
And in both cases the server does choose to use the index rather than do a
tablescan - so the optimiser thinks that it's more beneficial.
Now, mind that with the InnoDB storage engine a secondary index (such as
autoload) causes a double lookup. That is, once it finds an entry in such
an index, it has a pointer to the primary key where it then has to look up
the rest of the row. So there is a cost to using a secondary index (rather
than scanning the table using the clustered PRIMARY KEY), and the
optimiser knows it.
With this in mind, I think we can safely say that having the index makes
sense. It may not make a huge difference per query, but WP does a lot of
queries and thus every optimisation helps.
> There would be no benefit to switching to enum. Even assuming a
ludicrously massive wp_options table of 5000 rows, the space saving would
still be less than a single InnoDB page.
Indeed, an ENUM would not help.
But an index does. Please add it. Cheap gain!
--
Ticket URL: <https://core.trac.wordpress.org/ticket/14258#comment:8>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list