MySQL查詢中不使用索引的情況
explain顯示了MySQL如何使用索引來處理select語句以及連線表。可以幫助選擇更好的索引和寫出更優化的查詢語句。簡單講,它的作用就是分析查詢效能。
explain關鍵字的使用方法很簡單,就是把它放在select查詢語句的前面
具體參照:MySQL的Explain關鍵字檢視是否使用索引1) 如果MySQL估計使用索引比全表掃描更慢,則不使用索引。例如,如果列key均勻分佈在1和100之間,下面的查詢使用索引就不是很好:select * from table_name where key>1 and key<90;
2) 如果使用MEMORY/HEAP表,並且where條件中不使用
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後面是子查詢,則不會使用索引。