MySQL 性能分析 之 聯合索引(複合索引)實踐分析

MySQL 性能分析 之 聯合索引(複合索引)實踐分析

做爲開發者,你們都知道,一個服務器、一個數據庫的性能是項目的重中之重,後臺架構、寫法與數據庫設計的好壞每每直接影響到整個項目的性能。mysql

索引:是當你的業務完成後,跟據查詢條件來創建的。當你的數據量大(通常是10萬條數據)了以後,咱們會再把普通索引刪除,使用自建索引表。由於數據量大的時候你要批量修改(索引表也會修改)會變的很是的慢!sql

這裏給分析一下MySQL的索引;索引分:普通索引和聯合索引,而索引的關鍵相信不少人也知道,用非主鍵字段進行查詢的時候MySQL在查詢的時候就是掃錶行爲,若是有索引的話,狀況就獲得了大大的改善。數據庫

加索引的時候,先建議使用單列索引一個一個加!而後再改進使用聯合索引!並且最好是根據本身的項目業務查詢來統計 哪些字段的使用率是多少 哪些字段組合在一次使用了多少次,由於今天分析的就是聯合索引並非在任何狀況下都命中的服務器

表結構markdown

mysql> show create table m_user\G;  
*************************** 1. row ***************************  Table: m_user Create Table: CREATE TABLE `m_user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` char(32) NOT NULL, `age` tinyint(4) NOT NULL, `school` char(128) NOT NULL, `status` tinyint(4) NOT NULL DEFAULT '1', PRIMARY KEY (`id`), KEY `name` (`name`,`age`,`status`) ) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8 1 row in set (0.00 sec) 

聯合索引字段: 
KEY name (name,age,status)架構

模擬了數據後 咱們來查看結果數據庫設計

  • [1 3 命中]

select * from m_user where name='leal' and status=1性能

mysql> desc select * from m_user where name='leal' and status=1 \G;  
*************************** 1. row ***************************  id: 1 select_type: SIMPLE  table: m_user partitions: NULL  type: ref possible_keys: name  key: name  key_len: 96  ref: const  rows: 1  filtered: 10.00  Extra: Using index condition 1 row in set, 1 warning (0.00 sec) 
  • [1 3 order by 3 命中]

select * from m_user where name='leal' and status=1 order by status descspa

mysql> desc select * from m_user where name='leal' and status=1 order by status desc \G;  
*************************** 1. row ***************************  id: 1 select_type: SIMPLE  table: m_user partitions: NULL  type: ref possible_keys: name  key: name  key_len: 96  ref: const  rows: 1  filtered: 10.00  Extra: Using index condition 1 row in set, 1 warning (0.00 sec) 
  • [2 3 不命中]

select * from m_user where age=10 and status=1設計

mysql> desc select * from m_user where age=10 and status=1 \G;  
*************************** 1. row ***************************  id: 1 select_type: SIMPLE  table: m_user partitions: NULL  type: ALL possible_keys: NULL  key: NULL  key_len: NULL  ref: NULL  rows: 1000  filtered: 1.00  Extra: Using where 1 row in set, 1 warning (0.00 sec) 
  • [1 in 命中]

select * from m_user where name in ('leal') and age<10

select * from m_user where name in ('leal') and age<10 order by school

mysql> desc select * from m_user where name in ('leal') and age<10 order by school *************************** 1. row *************************** id: 1 select_type: SIMPLE table: m_user partitions: NULL type: range possible_keys: name key: name key_len: 97 ref: NULL rows: 1 filtered: 100.00 Extra: Using index condition; Using filesort 1 row in set, 1 warning (0.00 sec) 
  • [1 between 不命中]

select * from m_user where name between 'leal' and 'tom'

select * from m_user where name between 'leal' and 'tom' order by school desc

mysql> desc select * from m_user where name between 'leal' and  'tom' order by school desc \G;  
*************************** 1. row ***************************  id: 1 select_type: SIMPLE  table: m_user partitions: NULL  type: ALL possible_keys: name  key: NULL  key_len: NULL  ref: NULL  rows: 1000  filtered: 22.38  Extra: Using where; Using filesort 1 row in set, 1 warning (0.00 sec) 
  • [1 <> 不命中]

select * from m_user where name<>'leal'

select * from m_user where name<>'leal' and age<10

select * from m_user where name<>'leal' and age<10 order by school desc

mysql> desc select * from m_user where name<>'leal' and age<10 order by school desc \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: m_user partitions: NULL type: ALL possible_keys: name key: NULL key_len: NULL ref: NULL rows: 1000 filtered: 33.30 Extra: Using where; Using filesort 1 row in set, 1 warning (0.00 sec) -------------------------------------------------------------- mysql> desc select * from m_user where name<>'leal'\G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: m_user partitions: NULL type: ALL possible_keys: name key: NULL key_len: NULL ref: NULL rows: 1000 filtered: 99.90 Extra: Using where 1 row in set, 1 warning (0.00 sec) 
  • [1 < 或 <= 命中]

select * from m_user where name < 'leal'

select * from m_user where name <= 'leal'

select * from m_user where name <= 'leal' and age<10

select * from m_user where name <= 'leal' and age<10 order by school desc

mysql> desc select * from m_user where name < 'leal' and age<10 order by school desc \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: m_user partitions: NULL type: range possible_keys: name key: name key_len: 96 ref: NULL rows: 1 filtered: 33.33 Extra: Using index condition; Using filesort 1 row in set, 1 warning (0.00 sec) 
  • [1 > 或 >= 不命中]

select * from m_user where name>'leal'

select * from m_user where name>='leal'

mysql> desc select * from m_user where name >= 'leal' and age<10 order by school desc \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: m_user partitions: NULL type: ALL possible_keys: name key: NULL key_len: NULL ref: NULL rows: 1000 filtered: 33.30 Extra: Using where; Using filesort 1 row in set, 1 warning (0.00 sec) 
  • [無where條件 直接order by 不命中]

select * from m_user order by name desc

mysql> explain select * from m_user order by name desc\G;  
*************************** 1. row ***************************  id: 1 select_type: SIMPLE  table: m_user partitions: NULL  type: ALL possible_keys: NULL  key: NULL  key_len: NULL  ref: NULL  rows: 1000  filtered: 100.00  Extra: Using filesort 1 row in set, 1 warning (0.13 sec) 

結束語

通常人和一個項目都是從小到大逐漸健壯的,前期通常的項目 直接加索引就夠了,保證命中率;當項目業務複雜到必定程度或者負載到必定程度的時候,就得刪除索引,自建索引表來管理數據庫的索引了。

本文爲做者原創,手碼不易,容許轉載,轉載後請以連接形式說明文章出處. 如轉載但不標明來源,後果自負。

相關文章
相關標籤/搜索