乙個非索引覆蓋型別的查詢,走主鍵還是走索引回表?mysql可能會在這個問題上選擇錯誤。
比如說一張表t1,表結構如下
mysql> show create table t1\g
*************************** 1. row ***************************
table: t1
create table: create table `t1` (
`id` int(11) not null auto_increment,
`id1` int(11) default null,
`id2` int(11) default null,
`id3` int(11) default null,
primary key (`id`),
key `id1` (`id1`),
key `id2` (`id2`)
) engine=innodb auto_increment=1000001 default charset=utf8mb4
表中共有100000萬條資料
mysql> select count(*) from t1;
+----------+
| count(*) |
+----------+
| 1000000 |
+----------+
1 row in set (3.77 sec)
針對於select * from t1 where id1=100;
這條sql,mysql有兩種方式去獲取正確的資料,第一是通過id1索引獲取正確的主鍵值,拿主鍵值取獲取對應的行資料;第二是直接通過主鍵索引進行掃瞄。
兩種都可以,mysql會粗略的計算cpu和磁碟消耗之後,選擇一種,但經常性的會出錯,如下:
mysql> explain select * from t1 where id1=100\g
*************************** 1. row ***************************
id: 1
select_type: ******
table: t1
partitions: null
type: all
possible_keys: id1
key: null
key_len: null
ref: null
rows: 1
filtered: 100.00
extra: using where
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from t1 force index(id1)where id1=100\g
*************************** 1. row ***************************
id: 1
select_type: ******
table: t1
partitions: null
type: ref
possible_keys: id1
key: id1
key_len: 5
ref: const
rows: 96
filtered: 100.00
extra: null
1 row in set, 1 warning (0.00 sec)
而通常的解決辦法無非有兩種,
如果選擇force index,後期不能隨意的刪除這條索引,不然業務sql就該操作了。
結論是無論什麼情況下,我們不能絕對信任優化器會幫助我們選擇正確的索引,選擇恰當的時間進行干預,才能保證sql的高效執行。
MySQL中in到底走不走索引?
mysql中explain關鍵字可以模擬mysql優化器執行sql語句,是乙個可以很好的分析sql語句或表結構的效能瓶頸。explain的使用方法 explain sql語句,下面我們先來執行下explain語句 explain select from user where created time...
mysql 索引 大於等於 走不走索引 最左字首
你可以認為聯合索引是闖關遊戲的設計 例如你這個聯合索引是state city zipcode 那麼state就是第一關 city是第二關,zipcode就是第三關 你必須匹配了第一關,才能匹配第二關,匹配了第一關和第二關,才能匹配第三關 你不能直接到第二關的 索引的格式就是第一層是state,第二層...
mysql索引回表
先索引掃瞄,再通過id去取索引中未能提供的資料,即為回表。建表mysql create table t id int primary key,k int not null,name varchar 16 index k engine innodb 如果語句是 select from t where ...