今天本來想跟蹤mysql5.6中的新特性index merge,結果在跟蹤的過程中,發現了乙個問題,即innodb的二級索引中 可能會包含主索引,當然這裡的包含並不是說二級索引的row裡面會有pk的記錄,這一點是一直存在的,這裡的包含 是指,二級索引也會包含主索引進行排序。
mysql> show create table index_merge\g*************************** 1. row ***************************
table: index_merge
create table: create table `index_merge` (
`c1` int(11) not null auto_increment,
`c2` int(11) default null,
`c3` varchar(100) default null,
primary key (`c1`),
key `c2` (`c2`)
) engine=innodb auto_increment=10002 default charset=latin1
1 row in set (0.00 sec)
mysql> show create procedure fill_index_merge\g
*************************** 1. row ***************************
procedure: fill_index_merge
sql_mode: no_engine_substitution
create procedure: create definer=`root`@`127.0.0.1` procedure `fill_index_merge`(c1_cnt int, c2_cnt int)
begin
declare i,j int default 1;
repeat
repeat
insert into index_merge(c2,c3) values(j, repeat('a', 64));
set j = j+1;
until j > c2_cnt
end repeat;
set i = i + 1;
set j = 1;
until i > c1_cnt
end repeat;
endcharacter_set_client: utf8
collation_connection: utf8_general_ci
database collation: latin1_swedish_ci
1 row in set (0.00 sec)
mysql> call fill_index_merge(100, 100);
mysql> explain select * from index_merge where c1 < 100 and c2 = 50\g可以看到,計畫中竟然是range的查詢,我的第一直覺應該是ref const的查詢,但是確實是range,使用c2的range, 但是c2的key_len竟然是9,我去,各種疑惑啊,於是跟蹤計畫生成,發現key有兩個(primary, c2),但是c2的index上的列確有兩列,(c2,c1)。 瞬間凌亂了,竟然隱式的修改我的index,還把使用者蒙在鼓裡。*************************** 1. row ***************************
id: 1
select_type: ******
table: index_merge
type: range
possible_keys: primary,c2
key: c2
key_len: 9
ref: null
rows: 1
extra: using index condition
1 row in set (0.00 sec)
由上面的分析,可以知道c2的index在生成時,其實被mysql隱式修改為(c2,c1)的index了,那我們就看下**吧。
一開始我以為這些修改是在建立表的時候就隱式的修改了,我又錯了,木有,看遍了mysql_create_frm()都沒找到**修改了, frm檔案還是那個frm檔案。
ok,不是建立的時候修改,那只能是載入frm時候修改了,也就是記憶體的修改。看看資料字典的載入函式open_binary_frm(),bingo, 5.6相比5.5確實做了修改,重點**如下:
open_binary_frm()share->key_parts+= keyinfo->hidden_key_parts;
}...
} ...
}
重點來了,首先只有innodb引擎才支援隱式修改second index,然後是通過add_pk_parts_to_sk()函式將pk的列 加入到second index中,當然加入過程中有些限制,如對key中可列數和key的長度的限制。
innodb引擎原本的二級索引中的記錄就會包含pk的列,之前只是為了通過二級索引去定位主索引,也就時pk和second key之間資料 的一一對映,並沒有別的用途,現在增加了在sk中對pk的排序,可以說是在沒有增加儲存開銷的情況下,使得記錄有序性更強,也就是 更加有利於最優計畫的生成。當然代價可能就是插入時候key compare的時間會稍微變長。
總的來說,innodb在不斷完善,oracle也可以說是功不可沒吧,雖然我個人很討厭oracle現在把mysql搞的沒什麼活力了,很多東西不再那麼open了, 比如mysql-test的test case,bug系統等,希望oracle能把mysql做的更好吧。
from : (原始碼大牛)
mysql5 6亂碼 mysql5 6亂碼
安裝mysql5.6版本遇到乙個問題,字符集亂碼,如下圖 由於是新安裝的本地資料庫,所以一定是配置的事情,查詢資料庫字符集配置,如下 有兩個是latin1的字符集,本人是window7環境,在網路找了很多資料,都顯示為修改 c program files mysql mysql server 5.6...
編譯mysql5 6 編譯安裝mysql5 6
mysqlwget tar zxvf mysql 5.6.33.tar.gz tar zxvf cmake 2.8.5.tar.gz cd cmake 2.8.5 安裝編譯工具.bootstrap prefix usr local cmake sudo gmake sudo gmake instal...
mysql5 6cmd亂碼 mysql5 6亂碼
安裝mysql5.6版本遇到乙個問題,字符集亂碼,如下圖 由於是新安裝的本地資料庫,所以一定是配置的事情,查詢資料庫字符集配置,如下 有兩個是latin1的字符集,本人是window7環境,在網路找了很多資料,都顯示為修改 c program files mysql mysql server 5.6...