问题
Here's what I did:
MariaDB []> explain select * from blabla where name like '%poor%';
+------+-------------+--------------+------+---------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+--------------+------+---------------+------+---------+------+---------+-------------+
| 1 | SIMPLE | blabla | ALL | NULL | NULL | NULL | NULL | 8358772 | Using where |
+------+-------------+--------------+------+---------------+------+---------+------+---------+-------------+
1 row in set (0.01 sec)
MariaDB [bd]>show create table blabla;
| blabla | CREATE TABLE `blabla` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
PRIMARY KEY (`id`),
KEY `name` (`name`(252))
) ENGINE=InnoDB AUTO_INCREMENT=8372852 DEFAULT CHARSET=utf8
So if you watch: there's a key on 'name' and explain tells me "possible_keys" -> NULL. What shall I do to make this faster:
MariaDB []>select * from blabla where name like '%poor%';
********
********
491 rows in set (26.20 sec)
MariaDB []>WHAT??? 26 seconds on a 8 373 116 rows table? ARE YOU KIDDIN'?
ERROR 1064 (42000): You have an error
回答1:
MySQL (and MariaDB) cannot make effective use of an index to satisfy the predicate.
name LIKE '%poor%'
Consider the possible value of name that would satisfy that condition, and where they could appear in the index. For example, values 'aaapoor' and 'zzzpoor' satisfy the condition. A value that satisfies the condition could appear anywhere in the index, as the first value/row in the index, or as the last value/row in the index, or anywhere in between.
So, MySQL has to evaluate that predicate for every row in the table. Every single row has to be checked.
MySQL can't use an index to eliminate any rows from being checked. The way that an index would improve performance for a predicate such as col = 'foo' is that MySQL can very quickly eliminate vast swaths of rows that do not need to be checked, because of where they appear in the index. MySQL can quickly eliminate a boatload of rows, and narrow in on the index pages that do need to be checked. That's how an index improves performance.
And MySQL can't do that with the predicate in your query. That's why no index is being used.
If there was a "covering" index for the query, MySQL might use that. For example, if you were selecting just the name column, MySQL could satisfy the query from just the index pages, without a need to visit the underlying data pages.
Or, if you had an "order by" on name (or a leading column or columns in an index), MySQL might make use of an index to avoid a "Using filesort" operation.
If you want to search for "words" that appear in a VARCHAR column, you might want to consider using a FULLTEXT index. In older versions of MySQL, those were supported only on MyISAM tables. Newer versions (>=5.6?) of MySQL support FULLTEXT indexes on InnoDB tables as well.
A fulltext search uses a different operation in the predicate (it's not a LIKE comparison.)
来源:https://stackoverflow.com/questions/30281033/why-doesnt-mysql-use-the-key-for-a-simple-select