1. 程式人生 > >mysql索引研究

mysql索引研究

ike 反向索引 數據量 性能 一個 唯一性 explain into 全部

mysql索引研究

1. 為什麽使用索引 在無索引的情況下,MySQL會掃描整張表來查找符合sql條件的記錄,其時間開銷與表中數據量呈正相關。對關系型數據表中 的某些字段建索引可以極大提高查詢速度(當然,不同字段是否selective會導致這些字段建立的索引對查詢速度的提升幅 度不同,而且索引也並非越多越好,因為寫入或刪除時需要更新索引信息)。 2.索引的類型: 唯一索引, 全文索引, 組合索引, 反向索引, 函數索引 註意: 當查詢第一個使用了不走索引的條件整個語句都不會走索引 3.SQL什麽條件使用索引 1)=>>=
<<= 、BETWEEN或者IN操作符時使用索引。 2)若like語句的條件是不以通配符開頭的常量串,MySQL也會使用索引,如 LIKE XXX%,則走索引。 3)若已對名為col_name的列建了索引,則形如"col_name is null"的SQL會用到索引 4.MySQL使用索引的場景 1)若where條件使用了多個索引字段,則MySQL會優先使用能使候選記錄集規模最小的那個索引,以便盡快淘汰不符合條件的記錄。 2)如果表中存在幾個字段構成的聯合索引,則查找記錄時,這個聯合索引的最左前綴匹配字段也會被自動作為索引來加速查找。 例如,若為某表創建了3個字段(c1, c2, c3)構成的聯合索引,則(c1), (c1, c2), (c1, c2, c3)均會作為索引, (c2, c3)就不會被作為索引,而(c1, c3)其實只利用到c1索引。
4) 多表做join操作時會使用索引(如果參與join的字段在這些表中均建立了索引的話) 5) 若某字段已建立索引,求該字段的min()或max()時,MySQL會使用索引 6) 對建立了索引的字段做sort或group操作時,MySQL會使用索引 5.索引的創建 1)單列索引(普通索引這個是最基本的索引) 第一種方式 create index 索引名 on 表名 (字段); 第一種方式 alter table 表名 add index 索引名 (字段); 2)唯一索引
create unique index 索引名 on 表名 (字段); 3)組合索引 create index 索引名 ON 表名(字段1,字段2,字段3); 3)全文索引 文本字段上(text)如果建立的是普通索引,那麽只有對文本的字段內容前面的字符進行索引,其字符大小根據索引建立索引 時申明的大小來規定. 如果文本中出現多個一樣的字符,而且需要查找的話,那麽其條件只能是 where column lick %xxxx% 這樣做會讓索引失效 .這個時候全文索引就祈禱了作用了 ALTER TABLE 索引名 ADD FULLTEXT(column1, column2) 有了全文索引,就可以用SELECT查詢命令去檢索那些包含著一個或多個給定單詞的數據記錄了。 ELECT * FROM tablename WHERE MATCH(column1, column2) AGAINST(‘xxx′, ‘sss′, ‘ddd′) 這條命令將把column1和column2字段裏有xxx、sss和ddd的數據記錄全部查詢出來。 (一)使用索引的優點 1.可以通過建立唯一索引或者主鍵索引,保證數據庫表中每一行數據的唯一性. 2.建立索引可以大大提高檢索的數據,以及減少表的檢索行數 3.在表連接的連接條件 可以加速表與表直接的相連 4.在分組和排序字句進行數據檢索,可以減少查詢時間中 分組 和 排序時所消耗的時間(數據庫的記錄會重新排序) 5.建立索引,在查詢中使用索引 可以提高性能 (二)使用索引的缺點 1.在創建索引和維護索引 會耗費時間,隨著數據量的增加而增加 2.索引文件會占用物理空間,除了數據表需要占用物理空間之外,每一個索引還會占用一定的物理空間 3.當對表的數據進行 INSERT,UPDATE,DELETE 的時候,索引也要動態的維護,這樣就會降低數據的維護速度,(建立 索引會占用磁盤空間的索引文件。一般情況這個問題不太嚴重,但如果你在一個大表上創建了多種組合索引,索引文件的會膨脹很快)。 (三)使用索引需要註意的地方 在建立索引的時候應該考慮索引應該建立在數據庫表中的某些列上面 哪一些索引需要建立,哪一些所以是多余的. 一般來說, 1.在經常需要搜索的列上,可以加快索引的速度 2.主鍵列上可以確保列的唯一性 3.在表與表的而連接條件上加上索引,可以加快連接查詢的速度 4.在經常需要排序(order by),分組(group by)和的distinct 列上加索引 可以加快排序查詢的時間, (單獨order by 用不了索引,索引考慮加where 或加limit) 5.在一些where 之後的 < <= > >= BETWEEN IN 以及某個情況下的like 建立字段的索引(B-TREE) 6.like語句的 如果你對nickname字段建立了一個索引.當查詢的時候的語句是 nickname lick %ABC% 那麽這個 索引講不會起到作用.而nickname lick ABC% 那麽將可以用到索引 7.索引不會包含NULL列,如果列中包含NULL值都將不會被包含在索引中,復合索引中如果有一列含有NULL值那麽這個 組合索引都將失效,一般需要給默認值0或者 字符串 8.使用短索引,如果你的一個字段是Char(32)或者int(32),在創建索引的時候指定前綴長度 比如前10個字符 (前 提是多數值是唯一的..)那麽短索引可以提高查詢速度,並且可以減少磁盤的空間,也可以減少I/0操作. 9.不要在列上進行運算,這樣會使得mysql索引失效,也會進行全表掃描 10.選擇越小的數據類型越好,因為通常越小的數據類型通常在磁盤,內存,cpu,緩存中 占用的空間很少,處理起來更快 (四)什麽情況下不創建索引 1.查詢中很少使用到的列 不應該創建索引,如果建立了索引然而還會降低mysql的性能和增大了空間需求. 2.很少數據的列也不應該建立索引,比如 一個性別字段 0或者1,在查詢中,結果集的數據占了表中數據行的比例比較大,mysql需要掃描的行數很多,增加索引,並不能提高效率 3.定義為text和image和bit數據類型的列不應該增加索引, 4.當表的修改(UPDATE,INSERT,DELETE)操作遠遠大於檢索(SELECT)操作時不應該創建索引,這兩個操作是互斥的關系 為了形象地介紹索引,再建一個表: create table muser ( id bigint (22) not null auto_increment, name varchar(300) default null comment 用戶名, age varchar(300) default null comment 年齡, address varchar(300) default null comment 地址, primary key(id) )engine=innodb auto_increment=1 default charset=utf8 select * from muser; insert into muser(name, age, address) select name,age,上海浦東新區陸家嘴 from emp; insert into `muser` (`id`, `name`, `age`, `address`) values(1,test02,25,上海浦東新區唐鎮高科技園); insert into `muser` (`id`, `name`, `age`, `address`) values(3,馬風雷,30,浙江杭州金融大廈201號12室); ## 創建索引 ## 第一種方式 CREATE INDEX INDEX_NAME ON MUSER(NAME) ## 第二種方式 ALTER TABLE MUSER ADD INDEX INDEX_ADDRESS(ADDRESS) ## 刪除索引 DROP INDEX ADDRESS ON MUSER SHOW INDEX FROM MUSER ## 不走索引 第一個使用了不走索引的條件整個語句都不會走索引 EXPLAIN SELECT * FROM MUSER WHERE NAME LIKE %李% AND AGE = 48 AND NAME = 小鄭 AND ADDRESS LIKE %上海浦東新區% ## 走name和address索引 EXPLAIN SELECT * FROM MUSER WHERE AGE = 48 AND NAME = 小鄭 AND ADDRESS LIKE 上海浦東新區%
技術分享圖片
## 走name索引
EXPLAIN SELECT * FROM MUSER WHERE  AGE = 48 AND NAME = 小鄭 AND ADDRESS  LIKE %上海浦東新區%
## 不走索引
EXPLAIN SELECT * FROM MUSER WHERE ID = 2
EXPLAIN SELECT * FROM MUSER

EXPLAIN SELECT * FROM MUSER WHERE NAME  = 小鄭;
## 走索引 以XX開頭的會做索引  其余不走索引
EXPLAIN SELECT * FROM MUSER WHERE NAME  LIKE 李%
## 以下like不走索引
EXPLAIN SELECT * FROM MUSER WHERE NAME  LIKE %李%
EXPLAIN SELECT * FROM MUSER WHERE NAME  LIKE %李

## 走name索引
EXPLAIN SELECT * FROM muser WHERE NAME IS NOT NULL
EXPLAIN SELECT * FROM muser WHERE NAME IN(小鄭,test);

## 創建唯一索引
CREATE UNIQUE INDEX primary_name  ON muser (NAME);

## 創建組合索引
CREATE INDEX  index_age_name_address ON muser(NAME(13),address(20),age)

技術分享圖片
DROP INDEX index_age_name_address ON muser
/*
  建表時,name長度為50,這裏為什麽使用13呢,因為一般情況下名字的長度不會超過10,這樣會加速索引查詢速度

 肯定有人要問了,如果分別在 name,address,age 上建立單列索引,讓該表有 3 個單列索引,查詢時和上述的組合索引效率一樣嗎?
  大不一樣,遠遠低於我們的組合索引。雖然此時有了三個索引,但 MySQL 只能用到其中的那個它認為似乎是最有效率的單列索引。

 建立這樣的組合索引,其實是相當於分別建立了
  (name,address,age) (name,address) (name)
  
 這樣的三個組合索引!為什麽沒有 address,age 等這樣的組合索引呢?這是因為 mysql 組合索引“最左前綴”的結果。簡單的理解就
  是只從最左面的開始組合。並不是只要包含這三列的查詢都會用到該組合索引,下面的幾個 T-SQL 會用到:

 下面幾個會用到:
  SELECT * FROM muser WHREE Name="erquan" AND address="鄭州"
  SELECT * FROM muser WHREE Name="erquan"
  
 而下面幾個則不會用到:
  SELECT * FROM myIndex WHREE Age=20 AND address="鄭州" 
  SELECT * FROM myIndex WHREE address="鄭州"

mysql索引研究