MySQL是一個開放原始碼的小型關聯式資料庫管理系統,開發者為瑞典MySQL AB公司。目前MySQL被廣泛地應用在Internet上的中小型網站。由於其體積小、速度快、整體擁有成本低,尤其是開放原始碼這一特點,許多中小型網站為了降低網站總體擁有成本而選擇了MySQL作為網站資料庫。
MySQL開發團隊於12日宣布MySQL 8.0.0開發里程碑版本(DMR)發表!或許有人會驚訝MySQL為何從5.x一下跳躍到了8.0。事實上,MySQL 5.x系列已經延續了很多年,從被Oracle收購之前就是5.1,而收購之後一直維持在5.x,例如5.5,5.6,5.7等等。其實,如果按照原本的發布節奏,可以把5.6.x當成6.x,5.7.x當成7.x。所以,只是換了版本命名方式而已。
不過這次發表的MySQL 8.0.0開發版本還是有不少亮點的。
MySQL 8.0.0亮點
事務性資料字典,完全脫離了MyISAM儲存引擎
真正將資料字典放到了InnoDB中的一些表中,從此不再需要FRM、TRG、PAR文件啦! Information Schema現在以資料字典表的一個視圖出現。原則上可以完全不需要MyISAM資料表類型了,所有的系統表都可以放到InnoDB之中。
SQL角色
角色是一系列權限的集合。可以創建角色,給某個使用者授予和移除角色。這對於權限管理很方便。
utf8mb4字元集將成為預設字元集,並支援Unicode 9
預設字元集將從 latin1 改為 utf8mb4,預設定序collation將從latin1_swedish_ci 改為 utf8mb4,預設定序collation將從latin1_swedish_ci 改為 utf8mb4_800_ci_mbai。
不可見索引
可以將一些索引設為不可見,這樣SQL優化器就不會用到它,但它會繼續在背景中保持更新。當有需要時,可以隨時恢復可見。
對二進位資料可以進行位元操作
不僅可以對 BIGINT進行位元操作,從8.0開始也支援對 [VAR]BINARY/[TINY|MEDIUM|LONG]BLOB進行位元操作了。
改進了對IPv6和UUID的操作
INET6_ATON() 和 INET6_NTOA() 現在可以進行位元操作了,因為INET6_ATON()現在回傳的是VARBINARY(16) 資料(128位元)。改良了UUID操作,引進了三個新的函數 UUID_TO_BIN(), BIN_TO_UUID()和 IS_UUID() 。 MySQL並沒有特殊的IPv6和UUID資料類型,而是以VARBINARY(16) 資料類型保存的。
持續性的全域變數
可以用 SET PERSIST 來設定持久性的全域變量,即便伺服器重新啟動也會維持下來。
效能資料庫Performance Schema的改進
例如對效能資料庫增加了100多個索引,可以檢索更快。
重構SQL分析器
持續不斷的逐步改良SQL分析器。舊的分析器由於其語法複雜性和自頂向下的分析方式從而有嚴重的限制,導致難以維護和擴展。
成本模型
InnoDB緩衝區現在可以估算主記憶體快取區中的有多少資料表和索引,這可以讓最佳化器選擇存取方式時知道資料是否可以儲存在記憶體中還是必須儲存到磁碟上。
直方圖Histograms
透過使用直方圖,使用者或DBA可以對資料分佈進行統計,這可以用於查詢最佳化以尋找最佳化的查詢方案。
改進掃描效能
改進了InnoDB範圍查詢的效能,可提升全表查詢和範圍查詢 5-20%的效能。
重構BLOB
重構BLOB加速了片段讀取/更新操作,可以加速JSON資料的操作。
持久化自增值
InnoDB會持久化保持自增序列的最大值到redo日誌中。這個改進還修復了一個非常老的199號bug。
臨時表
取消對壓縮臨時表的支持,並將臨時表的元資料儲存到記憶體中。
其它的更多重要改進和細節,請參考MySQL 8.0.0 發佈公告[1]和這裡[2]。
下載
目前8.0.0還是開發版本,如果你希望體驗和測試最新特性,可以從 dev.mysql.com[3] 下載各平台的安裝套件。不過,MySQL軟體包是越來越大了,Linux平台上的二進位打包後就將近有1 GB。如果在產品環境中使用,在8.0沒有進入穩定版本之前,請繼續使用5.7系列,目前最新的版本是5.7.15 GA版本——這只有600 M多。
最新的原始碼放在 GitHub 上,有興趣的朋友可以去看看,其中有不少是中國人的貢獻。
從MySQL8.0開始支援隱藏索引特性,也就是所謂的invisible index。對於不可見的索引,優化器將直接忽略。我們可以透過該特性來影響優化器的行為。另外這也可以視為在drop一個索引之前的緩衝,暫時把索引設為不可見後,再觀察應用是否正常或有報錯什麼的,如果一切OK,再最終刪除。
對應的8.0.0的release note:
測驗
# 创建一个普通的表t1,只带主键 mysql> create table t1 (a int primary key auto_increment, b int, c int, d int); Query OK, 0 rows affected (0.67 sec) # 增加一个索引 mysql> alter table t1 add key(b); Query OK, 0 rows affected (0.06 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show indexes from t1\G *************************** 1. row *************************** Table: t1 Non_unique: 0 Key_name: PRIMARY Seq_in_index: 1 Column_name: a Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: Index_type: BTREE Comment: Index_comment: Visible: YES *************************** 2. row *************************** Table: t1 Non_unique: 1 Key_name: b Seq_in_index: 1 Column_name: b Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: YES Index_type: BTREE Comment: Index_comment: Visible: YES 2 rows in set (0.01 sec) 从show indexes的visible列显示了,这两个索引都是可见的。 # Load some data insert into t1 select NULL, rand()*100000, rand()*10000,rand()*10000; insert into t1 select NULL, rand()*100000, rand()*10000,rand()*10000 from t1; insert into t1 select NULL, rand()*100000, rand()*10000,rand()*10000 from t1; .... analyze table t1; mysql> explain select * from t1 where b > 5000 limit 10; +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+ | 1 | SIMPLE | t1 | NULL | range | b | b | 5 | NULL | 1932 | 100.00| Using index condition | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+ 1 row in set, 1 warning (0.00 sec 可以看到索引b被使用到 # 修改索引b为不可见 mysql> alter table t1 alter index b invisible; Query OK, 0 rows affected (0.05 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show indexes from t1\G *************************** 1. row *************************** Table: t1 Non_unique: 0 Key_name: PRIMARY Seq_in_index: 1 Column_name: a Collation: A Cardinality: 2048 Sub_part: NULL Packed: NULL Null: Index_type: BTREE Comment: Index_comment: Visible: YES *************************** 2. row *************************** Table: t1 Non_unique: 1 Key_name: b Seq_in_index: 1 Column_name: b Collation: A Cardinality: 2029 Sub_part: NULL Packed: NULL Null: YES Index_type: BTREE Comment: Index_comment: Visible: NO 2 rows in set (0.01 sec) mysql> explain select * from t1 where b > 5000 limit 10\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t1 partitions: NULL type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 2048 filtered: 33.33 Extra: Using where 1 row in set, 1 warning (0.00 sec) 当索引被修改为invisible后,优化器将不再选择这个索引 # 将索引重新修改为可见 mysql> alter table t1 alter index b visible; Query OK, 0 rows affected (0.05 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> explain select * from t1 where b > 5000 limit 10\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t1 partitions: NULL type: range possible_keys: b key: b key_len: 5 ref: NULL rows: 1932 filtered: 100.00 Extra: Using index condition 1 row in set, 1 warning (0.00 sec) # 你也可以在创建索引的时候显式指定是否可见 mysql> alter table t1 add key(c) invisible; Query OK, 0 rows affected (0.12 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show indexes from t1 where key_name = 'c'\G *************************** 1. row *************************** Table: t1 Non_unique: 1 Key_name: c Seq_in_index: 1 Column_name: c Collation: A Cardinality: 1848 Sub_part: NULL Packed: NULL Null: YES Index_type: BTREE Comment: Index_comment: Visible: NO 1 row in set (0.01 sec) # 或者在建表时指定关键字 mysql> create table t2 (a int primary key, b int, key(b) invisible); Query OK, 0 rows affected (0.67 sec) # 但primary key不可以设置为不可见 mysql> drop table t2; Query OK, 0 rows affected (0.03 sec) mysql> create table t2 (a int, b int, primary key(a) invisible); ERROR 3522 (HY000): A primary key index cannot be invisible