程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> mysql優化之索引篇

mysql優化之索引篇

編輯:MySQL綜合教程

對mysql優化是一個綜合性的技術,主要包括

a: 表的設計合理化(符合3NF)

b: 添加適當索引(index) [四種: 普通索引、主鍵索引、唯一索引unique、全文索引]

c: 分表技術(水平分割、垂直分割)

d: 讀寫[寫: update/delete/add]分離

e: 存儲過程 [模塊化編程,可以提高速度]

f: 對mysql配置優化 [配置最大並發數my.ini, 調整緩存大小 ]

g: mysql服務器硬件升級

h: 定時的去清除不需要的數據,定時進行碎片整理(MyISAM)

i: sql語句優化

 

本篇主要總結下索引有關內容

索引
四種索引(主鍵索引/唯一索引/全文索引/普通索引)

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
    [USING index_type]
    ON tbl_name (index_col_name,...)
 
index_col_name:
    col_name [(length)] [ASC | DESC]  (列部分值作為索引) 

 

列部分值作為索引::
對於CHAR和VARCHAR列,只用一列的一部分就可創建索引。
創建索引時,使用col_name(length)語法,對前綴編制索引。
前綴包括每列值的前length個字符。

BLOB和TEXT列也可以編制索引,但是必須給出前綴長度。

此處展示的語句用於創建一個索引,索引使用列名稱的前10個字符。
CREATE INDEX part_of_name ON customer (name(10));

因為多數名稱的前10個字符通常不同,所以此索引不會比使用列的全名創建的索引速度慢很多。
另外,使用列的一部分創建索引可以使索引文件大大減小,從而節省了大量的磁盤空間,有可能提高INSERT操作的速度。

前綴最長為255字節。對於MyISAM和InnoDB表,前綴最長為1000字節。
注意前綴的限長以字節計,而CREATE INDEX語句中的前綴長度指的是字符的數目。
對於使用多字節字符集的列,在指定列的前綴長度時,要考慮這一點。

在MySQL 5.1中:
·         只有當您正在使用MyISAM, InnoDB或BDB表類型時,您可以向有NULL值的列中添加索引。
·         只有當您正在使用MyISAM, BDB或InnoDB表類型時,您可以向BLOB或TEXT列中添加索引。



index_type::
部分儲存引擎允許在創建索引時指定索引類型。
index_type指定語句的語法是USING type_name。
不同的儲存引擎所支持的type_name值已顯示在下表中。
如果列有多個索引類型,當沒有指定index_type時,第一個類型是默認值。

存儲引擎    允許的索引類型 MyISAM  BTREE InnoDB   BTREE MEMORY/HEAP  HASH, BTREE



        
       
   

主鍵索引::
當一張表,把某個列設為主鍵的時候,則該列就是主鍵索引
1,create table testtable
(id int unsigned primary key auto_increment ,
name varchar(32) not null defaul '');

2,alter table 表名 add primary key (列名);


普通索引::
一般來說,普通索引的創建,是先創建表,然後在創建普通索引
比如:
create table ccc(
id int unsigned,
name varchar(32)
)

create index 索引名 on 表 (列1,列名2);



全文索引::
1,FULLTEXT索引只能對CHAR, VARCHAR和TEXT列編制索引,
2,在mysql中fulltext 索引只針對 myisam生效
3,mysql自己提供的fulltext針對英文生效->sphinx (coreseek) 技術處理中文
4,使用方法是 match(字段名..) against(‘關鍵字’)
5,全文索引一個 叫 停止詞,  因為在一個文本中,創建索引是一個無窮大的數,
6,因此,對一些常用詞和字符,就不會創建,這些詞,稱為停止詞.
7,任何過於短的詞都會被忽略。 全文搜索所能找到的詞的默認最小長度為 4個字符。

8,MATCH()列列表必須同該表中一些 FULLTEXT索引定義中的列列表完全符合,除非MATCH()在IN BOOLEAN MODE(布爾全文搜索)。
9,對AGAINST() 的參數必須是一個常數字符串。 


創建 :

CREATE TABLE articles (
       id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
       title VARCHAR(200),
       body TEXT,
       FULLTEXT (title,body)
     )engine=myisam charset utf8;

INSERT INTO articles (title,body) VALUES
     ('MySQL Tutorial','DBMS stands for DataBase ...'),
     ('How To Use MySQL Well','After you went through a ...'),
     ('Optimizing MySQL','In this tutorial we will show ...'),
     ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
     ('MySQL vs. YourSQL','In the following database comparison ...'),
     ('MySQL Security','When configured properly, MySQL ...');

如何使用全文索引:
錯誤用法:
select * from articles where body like '%mysql%'; [不會使用到全文索引]
證明:
explain  select * from articles where body like '%mysql%'

正確的用法是:(match中的列值,跟定義fulltext時的一樣)
select * from articles where match(title,body) against('database'); 【可以】

 

 

唯一索引::
①當表的某列被指定為unique約束時,這列就是一個唯一索引
create table ddd(id int primary key auto_increment , name varchar(32) unique);
這時, name 列就是一個唯一索引.

②在創建表後,再去創建唯一索引
create table eee(id int primary key auto_increment, name varchar(32));
create unique index 索引名  on 表名 (列表..);

unique字段可以為NULL,並可以有多NULL, 但是如果是具體內容(例如 ''),則不能重復.
主鍵字段,不能為NULL,也不能重復.

 

索引查詢,刪除,修改::

desc 表名 【該方法的缺點是: 不能夠顯示索引名.】
show index(es) from 表名
show keys from 表名

alter table 表名 drop index 索引名;
    
先刪除,再重新創建.

 

索引使用的注意事項::
1.占用磁盤空間
2.對DML操作有影響,變慢(例如增加,刪除,修改),因數據庫操作中select占絕大部分,所以能有索引的地方最好還是用索引


例如:alter table dept add index my_ind (dname,loc); //  dname 左邊的列,loc就是右邊的列

3,對於創建的多列索引,只要查詢條件使用了最左邊的列,索引一般就會被使用。
explain select * from dept where loc='aaa'\G
就不會使用到索引


4,對於使用like的查詢,查詢如果是  '%aaa' 不會使用到索引,'aaa%' 會使用到索引。
比如: explain select * from dept where dname like '%aaa'\G
不能使用索引,即,在like查詢時,關鍵的 ‘關鍵字’ , 最前面,不能使用 % 或者 _這樣的字符.,
如果一定要前面有變化的值,則考慮使用 全文索引->sphinx.


5.如果條件中有or,即使其中有條件帶索引也不會使用。
  換言之,就是要求使用的所有字段,都必須建立索引, 我們建議大家盡量避免使用or 關鍵字

select * from dept where dname=’xxx’ or loc=’xx’ or deptno=45

6.如果列類型是字符串,那一定要在條件中將數據使用引號引用起來。
  否則不使用索引。(添加時,字符串必須''), 也就是,如果列是字符串類型,就一定要用 '' 把他包括起來.

7.如果mysql估計使用全表掃描要比使用索引快,則不使用索引。(有但少見,例如表中就一條數據)


適合創建索引的列應滿足::
a: 肯定在where條經常使用
b: 該字段的內容不是唯一的幾個值(sex:男或女  0或1)
c: 字段內容不是頻繁變化.


查看索引使用的情況::
show status like 'Handler_read%';
結果中
handler_read_key:這個值越高越好,越高表示使用索引查詢到的次數。
handler_read_rnd_next:這個值越高,說明查詢低效。

 

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved