改善性能最好的方式,就是經過數據庫中合理地使用索引,換句話說,索引是提升 MySQL 數據庫查詢性能的主要手段。在下面的章節中,介紹了索引類型、強制索引、全文索引。javascript
原文地址:服務端指南 數據存儲篇 | MySQL(03) 如何設計索引
博客地址:blog.720ui.com/java
MySQL 索引能夠分爲單列索引、複合索引、惟一索引、主鍵索引等。這裏,將爲讀者介紹這幾種索引的特色。mysql
單列索引:單列索引是最基本的索引,它沒有任何限制。算法
建立一個單列索引,例如:sql
create index index_name on tbl_name(index_col_name);複製代碼
同時,也能夠經過修改表結構的方式添加索引,例如:數據庫
alter table tbl_name add index index_name on (index_col_name);複製代碼
複合索引:複合索引是在多個字段上建立的索引。複合索引遵照「最左前綴」原則,即在查詢條件中使用了複合索引的第一個字段,索引纔會被使用。所以,在複合索引中索引列的順序相當重要。微信
建立一個複合索引,例如:app
create index index_name on tbl_name(index_col_name,...);複製代碼
同時,也能夠經過修改表結構的方式添加索引,例如:性能
alter table tbl_name add index index_name on (index_col_name,...);複製代碼
惟一索引:惟一索引和單列索引相似,主要的區別在於,惟一索引限制列的值必須惟一,但容許有空值。對於多個字段,惟一索引規定列值的組合必須惟一。優化
建立一個複合索引,例如:
create unique index index_name on tbl_name(index_col_name,...);複製代碼
同時,也能夠經過修改表結構的方式添加索引,例如:
alter table tbl_name add unique index index_name on (index_col_name,...);複製代碼
主鍵索引:主鍵索引是一種特殊的惟一索引,不容許有空值。此外, CREATE INDEX 不能建立主鍵索引,須要使用 ALTER TABLE 代替,例如:
alter table tbl_name add primary key(index_col_name);複製代碼
有時,由於使用 MySQL 的優化器機制,本來應該使用索引的優化器,反而選擇執行全表掃描或者執行的不是預期的索引。此時,能夠經過強制索引的方式引導優化器採起正確的執行計劃。
使用強制索引,SQL 語句只使用創建在 index_col_name 上的索引,而不使用其它的索引。
select * from tbl_name force index (index_col_name) …複製代碼
切記,不要濫用強制索引,由於 MySQL 的優化器會同時評估 I/O 和 CPU 的成本,通常狀況下,能夠自動分析選擇最合適的索引。
若是優化器成本評估錯誤,於是沒有選擇最佳方案,最好的方法應該是將合適的索引修改得更好。
若是某個 SQL 語句使用強制索引,須要在系統迭代開發過程當中時時維護強制索引,一方面,須要保證使用的強制索引最優,另一面,須要保證所使用的強制索引不能被誤刪,否則將致使 SQL 報錯。
所以,若是某個 SQL 語句必需要使用強制索引,建議在團隊內部開展嚴格地評審後纔可使用。
在通常狀況下,模糊查詢都是經過 like 的方式進行查詢。可是,對於海量數據,這並非一個好辦法,在 like "value%" 可使用索引,可是對於 like "%value%" 這樣的方式,執行全表查詢,這在數據量小的表,不存在性能問題,可是對於海量數據,全表掃描是很是可怕的事情,因此 like 進行模糊匹配性能不好。
這種狀況下,須要考慮使用全文搜索的方式進行優化。全文搜索在 MySQL 中是一個 FULLTEXT 類型索引。 FULLTEXT 索引在 MySQL 5.6 版本以後支持 InnoDB,而以前的版本只支持 MyISAM 表。
假設,有一張應用全文索引表。
CREATE TABLE IF NOT EXISTS `app_full_text` (
`app_id` bigint(20) NOT NULL,
`app_name_full_text` text NOT NULL,
`introduce_full_text` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;複製代碼
如今須要對應用的名稱建立全文索引,能夠這麼設計。
alter table `app_full_text` add fulltext key `app_name_intro` (`app_name_full_text`);複製代碼
默認 MySQL 不支持中文全文檢索,對此,網上的方案不少,例如添加 MySQL 擴展,或者將內容轉換成拼音的方式存儲在索引表,或者使用 IKAnalyzer 分詞庫等,其效果都不是很是的理想。使用拼音分詞,雖然能夠查詢到內容,可是若是拼音相同的狀況,是很是致命的,並且分詞的粒度也是個很可怕的問題。使用 IKAnalyzer 分詞庫,效果也不是很好。由於業務的須要,命中率也是很是重要的,有的關鍵字沒有進行分詞致使查詢不到的問題。
我以前的臨時解決方案。以下:
事實上,MySQL 全文搜索只是一個臨時方案,對於全文搜索場景,更專業的作法是使用全文搜索引擎,例如 ElasticSearch 或 Solr。
(完)
更多精彩文章,盡在「服務端思惟」微信公衆號!