MySQL高性能的索引策略(一)

MySQL高性能的索引策略(一)mysql

基於如下表結構sql

create table article(
id int auto_increment primary key,
title varchar(255) not null,
shortName varchar(255) not null,
authorId int not null,
createTime datetime not null,
state int  not null,
totalView int default null,
unique index idx_short_name_title (title,shortName)
);

create table user (
id int auto_increment primary key,
name varchar(255) not null,
sex bit default 0,
email varchar(50) not null, 
address varchar(255) default null,
unique index idx_email (email),
index idx_name (name)
);

insert into article (title,shortName,authorId,createTime,state,totalView) 
values ('hello world','hello-world-0',1,'2015-10-11 08:08:08',1,10),
('hello world','hello-world-1',1,'2015-10-11 08:08:08',2,10),
('hello world','hello-world-2',2,'2015-10-11 08:08:08',3,10),
('hello world','hello-world-3',3,'2015-10-11 08:08:08',4,10),
('hello world','hello-world-4',3,'2015-10-11 08:08:08',5,10);

insert into user (name,sex,email,address) values('lyx',0,'000@gmail.com','bj'),
('lyx',0,'111@gmail.com','bj'),
('lyx-0',0,'222@gmail.com','bj'),
('lyx-1',0,'333@gmail.com','bj');

獨立的列做爲索引

若是查詢中的列不是獨立的,則mysql就不會使用索引,獨立的列是指列不能是表達式的一部分,也不能是函數的參數。函數

> explain
select * from article where id +1 = 2

******************** 1. row *********************
           id: 1
  select_type: SIMPLE
        table: article
         type: ALL
possible_keys: 
          key: 
      key_len: 
          ref: 
         rows: 5
        Extra: Using where
1 rows in set

如上面所示,id時一個主鍵索引,但卻沒有使用索引查找數據,就是由於主鍵列不是單獨的列,而下面,性能

> explain
select * from article where id=1

******************** 1. row *********************
           id: 1
  select_type: SIMPLE
        table: article
         type: const
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: const
         rows: 1
        Extra: 
1 rows in set

一個type類型是all,而另外一個類型倒是const。spa


前綴索引和索引選擇性

有時候須要索引很長的字符串,這會讓索引變的大且慢。一個策略是前面提到過的模擬哈希索引。一般能夠索引開始的部分字符,這樣能夠大大節約索引空間,從而提升索引效率。可是這樣也會下降索引的選擇性。索引的選擇性是指,不重複的索引值。code

通常狀況下,某個列前綴的選擇性也是足夠高的,足以知足查詢性能。對於Blob,Text或者很長的VARCHAR類型的列,必須使用前綴索引,由於mysql不容許這些列的完整長度。訣竅在於要選擇足夠長的前綴以保證較高的選擇性,同時又不能太長(以便節約空間)。前綴應該足夠長,以便使得前綴索引的選擇性接近於索引整個列。索引

如何決定前綴的合適長度。使用以下sql,rem

> select count(*) as cnt , left(title,3) as pref from article group by pref order by cnt desc limit 10

******************** 1. row *********************
 cnt: 6
pref: hel
******************** 2. row *********************
 cnt: 2
pref: dem
******************** 3. row *********************
 cnt: 1
pref: dei
******************** 4. row *********************
 cnt: 1
pref: dii
4 rows in set

而後咱們在增長選擇的前綴的長度,字符串

> select count(*) as cnt , left(title,5) as pref from article group by pref order by cnt desc limit 10

******************** 1. row *********************
 cnt: 6
pref: hello
******************** 2. row *********************
 cnt: 1
pref: deii
******************** 3. row *********************
 cnt: 1
pref: demo
******************** 4. row *********************
 cnt: 1
pref: demo-
******************** 5. row *********************
 cnt: 1
pref: diiii
5 rows in set

這樣可選擇性就好一些了。最終前綴的長度多少更好,咱們能夠經過下面的sql來比較,it

> select count(distinct left(title,3)) / count(*)as pref3,
count(distinct left(title,4)) / count(*) as pref4,
count(distinct left(title,5)) / count(*) as pref5
from article

******************** 1. row *********************
pref3: 0.4000
pref4: 0.4000
pref5: 0.5000
1 rows in set

咱們能夠看到,當前綴長度3和4的時候是同樣的,當前綴長度爲5的時候,前綴索引的選擇性就降低了。

那麼肯定的索引前綴的長度爲3,而後創建索引。

alter table article add index idx_title(title(3));

==========END==========

相關文章
相關標籤/搜索