1. 程式人生 > >MySQL查詢中不使用索引的情況

MySQL查詢中不使用索引的情況

explain顯示了MySQL如何使用索引來處理select語句以及連線表。可以幫助選擇更好的索引和寫出更優化的查詢語句。簡單講,它的作用就是分析查詢效能

explain關鍵字的使用方法很簡單,就是把它放在select查詢語句的前面

具體參照:MySQL的Explain關鍵字檢視是否使用索引

1) 如果MySQL估計使用索引比全表掃描更慢,則不使用索引。例如,如果列key均勻分佈在1100之間,下面的查詢使用索引就不是很好:select * from table_name where key>1 and key<90;

2) 如果使用MEMORY/HEAP表,並且where條件中不使用

“=”進行索引列,那麼不會用到索引,head表只有在“=”的條件下才會使用索引

3) or分隔開的條件,如果or條件中的一個列有索引,其他的列沒有索引,那麼涉及到的索引都不會被用到,例如:select * from table_name where key1='a' or key2='b';如果在key1上有索引而在key2上沒有索引,則該查詢也不會走索引。

4) 複合索引,如果索引列不是複合索引的第一部分,則不使用索引(即不符合最左字首),例如,複合索引為(key1,key2),則查詢select * from table_name where key2='b';將不會使用索引。

CREATE TABLE `countrylanguage` (
  `CountryCode` char(3) NOT NULL DEFAULT '',
  `Language` char(30) NOT NULL DEFAULT '',
  `IsOfficial` enum('T','F') NOT NULL DEFAULT 'F',
  `Percentage` float(4,1) NOT NULL DEFAULT '0.0',
  PRIMARY KEY (`CountryCode`,`Language`),
  KEY `CountryCode` (`CountryCode`),
  CONSTRAINT `countryLanguage_ibfk_1` FOREIGN KEY (`CountryCode`) REFERENCES `country` (`Code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
mysql> select * from countrylanguage where CountryCode ='ABW';
+-------------+------------+------------+------------+
| CountryCode | Language   | IsOfficial | Percentage |
+-------------+------------+------------+------------+
| ABW         | Dutch      | T          |        5.3 |
| ABW         | English    | F          |        9.5 |
| ABW         | Papiamento | F          |       76.7 |
| ABW         | Spanish    | F          |        7.4 |
+-------------+------------+------------+------------+
4 rows in set

mysql> explain select * from countrylanguage where CountryCode ='ABW';
+----+-------------+-----------------+------------+------+---------------------+---------+---------+-------+------+----------+-------+
| id | select_type | table           | partitions | type | possible_keys       | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+-----------------+------------+------+---------------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | countrylanguage | NULL       | ref  | PRIMARY,CountryCode | PRIMARY | 3       | const |    4 |      100 | NULL  |
+----+-------------+-----------------+------------+------+---------------------+---------+---------+-------+------+----------+-------+
1 row in set

mysql> explain select * from countrylanguage where Language ='Dutch';
+----+-------------+-----------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table           | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | countrylanguage | NULL       | ALL  | NULL          | NULL | NULL    | NULL |  984 |       10 | Using where |
+----+-------------+-----------------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set

mysql> 



5) 如果like是以‘%’開始的,則該列上的索引不會被使用。例如select * from table_name where key1 like '%a';該查詢即使key1上存在索引,也不會被使用。

CREATE TABLE `country` (
  `Code` char(3) NOT NULL DEFAULT '',
  `Name` char(52) NOT NULL DEFAULT '',
  `Continent` enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL DEFAULT 'Asia',
  `Region` char(26) NOT NULL DEFAULT '',
  `SurfaceArea` float(10,2) NOT NULL DEFAULT '0.00',
  `IndepYear` smallint(6) DEFAULT NULL,
  `Population` int(11) NOT NULL DEFAULT '0',
  `LifeExpectancy` float(3,1) DEFAULT NULL,
  `GNP` float(10,2) DEFAULT NULL,
  `GNPOld` float(10,2) DEFAULT NULL,
  `LocalName` char(45) NOT NULL DEFAULT '',
  `GovernmentForm` char(45) NOT NULL DEFAULT '',
  `HeadOfState` char(60) DEFAULT NULL,
  `Capital` int(11) DEFAULT NULL,
  `Code2` char(2) NOT NULL DEFAULT '',
  PRIMARY KEY (`Code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

mysql> select * from country where Code like '%AB';
+------+-------+-----------+----------------+-------------+-----------+------------+----------------+------+--------+-----------+----------------+-------------+---------+-------+
| Code | Name  | Continent | Region         | SurfaceArea | IndepYear | Population | LifeExpectancy | GNP  | GNPOld | LocalName | GovernmentForm | HeadOfState | Capital | Code2 |
+------+-------+-----------+----------------+-------------+-----------+------------+----------------+------+--------+-----------+----------------+-------------+---------+-------+
| GAB  | Gabon | Africa    | Central Africa |      267668 |      1960 |    1226000 |           50.1 | 5493 |   5279 | Le Gabon  | Republic       | Omar Bongo  |     902 | GA    |
+------+-------+-----------+----------------+-------------+-----------+------------+----------------+------+--------+-----------+----------------+-------------+---------+-------+
1 row in set

mysql> EXPLAIN select * from country where Code like '%AB';
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | country | NULL       | ALL  | NULL          | NULL | NULL    | NULL |  239 |    11.11 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set

mysql> EXPLAIN select * from country where Code like 'AB%';
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | country | NULL       | range | PRIMARY       | PRIMARY | 3       | NULL |    1 |      100 | Using where |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set

6) 如果列為字串,則where條件中必須將字元常量值加引號,否則即使該列上存在索引,也不會被使用。例如,select * from table_name where key1=1;如果key1列儲存的是字串,即使key1上有索引,也不會被使用。

7) mysql會對sql語句做優化, in 後面的條件不超過一定數量仍然會使用索引。mysql 會根據索引長度和in後面條件數量判斷是否使用索引。另外,如果是in後面是子查詢,則不會使用索引。