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

我的MYSQL學習心得(九)

編輯:MySQL綜合教程

我的MYSQL學習心得(九)

 

我的MYSQL學習心得(一)

我的MYSQL學習心得(二)

我的MYSQL學習心得(三)

我的MYSQL學習心得(四)

我的MYSQL學習心得(五)

我的MYSQL學習心得(六)

我的MYSQL學習心得(七)

我的MYSQL學習心得(八)

 

這一篇《我的MYSQL學習心得(九)》將會講解MYSQL的索引

 

索引是在存儲引擎中實現的,因此每種存儲引擎的索引都不一定完全相同,並且每種存儲引擎也不一定支持所有索引類型。

根據存儲引擎定義每個表的最大索引數和最大索引長度。所有存儲引擎支持每個表至少16個索引,總索引長度至少為256字節。

大多數存儲引擎有更高的限制。MYSQL中索引的存儲類型有兩種:BTREE和HASH,具體和表的存儲引擎相關;

MYISAM和InnoDB存儲引擎只支持BTREE索引;MEMORY和HEAP存儲引擎可以支持HASH和BTREE索引

 

索引的優點:

1、通過創建唯一索引,保證數據庫表每行數據的唯一性

2、大大加快數據查詢速度

3、在使用分組和排序進行數據查詢時,可以顯著減少查詢中分組和排序的時間

 

索引的缺點:

1、維護索引需要耗費數據庫資源

2、索引需要占用磁盤空間,索引文件可能比數據文件更快達到最大文件尺寸

3、當對表的數據進行增刪改的時候,因為要維護索引,速度會受到影響

 

索引的分類

1、普通索引和唯一索引

主鍵索引是一種特殊的唯一索引,不允許有空值

2、單列索引和復合索引

單列索引只包含單個列

復合索引指多個字段上創建的索引,只有在查詢條件中使用了創建索引時的第一個字段,索引才會被使用。使用復合索引時遵循最左前綴集合

3、全文索引

全文索引類型為FULLTEXT,在定義索引的列上支持值的全文查找,允許在這些索引列中插入重復值和空值。全文索引可以在

CHAR、VARCHAR、TEXT類型列上創建。MYSQL只有MYISAM存儲引擎支持全文索引

4、空間索引

空間索引是對空間數據類型的字段建立的索引,MYSQL中的空間數據類型有4種,

分別是GEOMETRY、POINT、LINESTRING、POLYGON。

MYSQL使用SPATIAL關鍵字進行擴展,使得能夠用於創建正規索引類型的語法創建空間索引。創建空間索引的列,必須

將其聲明為NOT NULL,空間索引只能在存儲引擎為MYISAM的表中創建

 

以上的索引在SQLSERVER裡都支持

 

CREATE TABLE table_name[col_name data type]
[unique|fulltext|spatial][index|key][index_name](col_name[length])[asc|desc]

unique|fulltext|spatial為可選參數,分別表示唯一索引、全文索引和空間索引;

index和key為同義詞,兩者作用相同,用來指定創建索引

col_name為需要創建索引的字段列,該列必須從數據表中該定義的多個列中選擇;

index_name指定索引的名稱,為可選參數,如果不指定,MYSQL默認col_name為索引值;

length為可選參數,表示索引的長度,只有字符串類型的字段才能指定索引長度;

asc或desc指定升序或降序的索引值存儲


普通索引

CREATE TABLE book (
  bookid INT NOT NULL,
  bookname VARCHAR (255) NOT NULL,
  AUTHORS VARCHAR (255) NOT NULL,
  info VARCHAR (255) NULL,
  COMMENT VARCHAR (255) NULL,
  year_publication YEAR NOT NULL,
  INDEX (year_publication)
) ;

使用SHOW CREATE TABLE查看表結構

CREATE TABLE `book` (
  `bookid` INT(11) NOT NULL,
  `bookname` VARCHAR(255) NOT NULL,
  `authors` VARCHAR(255) NOT NULL,
  `info` VARCHAR(255) DEFAULT NULL,
  `comment` VARCHAR(255) DEFAULT NULL,
  `year_publication` YEAR(4) NOT NULL,
  KEY `year_publication` (`year_publication`)
) ENGINE=MYISAM DEFAULT CHARSET=latin1

可以發現,book表的year_publication字段成功建立了索引其索引名字為year_publication

 

我們向表插入一條數據,然後使用EXPLAIN語句查看索引是否有在使用

INSERT INTO BOOK VALUES(12,'NIHAO','NIHAO','文學','henhao',1990)


EXPLAIN SELECT * FROM book WHERE year_publication=1990 

 

因為語句比較簡單,系統判斷有可能會用到索引或者全文掃描

EXPLAIN語句輸出結果的各個行的解釋如下:

select_type: 表示查詢中每個select子句的類型(簡單 OR復雜)

type:表示MySQL在表中找到所需行的方式,又稱“訪問類型”,常見類型如下:(從上至下,效果依次變好)

possible_keys :指出MySQL能使用哪個索引在表中找到行,查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢使用

key: 顯示MySQL在查詢中實際使用的索引,若沒有使用索引,顯示為NULL

key_len :表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度

ref :表示上述表的連接匹配條件,即哪些列或常量被用於查找索引列上的值

rows :表示MySQL根據表統計信息及索引選用情況,估算的找到所需的記錄所需要讀取的行數

Extra :包含不適合在其他列中顯示但十分重要的額外信息 如using where,using index

 

參考:MySQL學習系列2--MySQL執行計劃分析EXPLAIN


唯一索引

唯一索引列的值必須唯一,但允許有空值。如果是復合索引則列值的組合必須唯一

建表

CREATE TABLE t1
(
 id INT NOT NULL,
 NAME CHAR(30) NOT NULL,
 UNIQUE INDEX UniqIdx(id)

SHOW CREATE TABLE t1 查看表結構

SHOW CREATE TABLE t1 
 CREATE TABLE `t1` (                                                                                                                        
          `id` int(11) NOT NULL,                                                                                                                   
          `name` char(30) NOT NULL,                                                                                                                
          UNIQUE KEY `UniqIdx` (`id`)                                                                                                              
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8     

可以看到id字段上已經成功建立了一個名為UniqIdx的唯一索引

 

創建復合索引

CREATE TABLE t3 (
  id INT NOT NULL,
  NAME CHAR(30) NOT NULL,
  age INT NOT NULL,
  info VARCHAR (255),
  INDEX MultiIdx (id, NAME, age (100))
)
SHOW CREATE TABLE t3

CREATE TABLE `t3` (                                                                                                                                                                                             
          `id` int(11) NOT NULL,                                                                                                                                                                                        
          `NAME` char(30) NOT NULL,                                                                                                                                                                                     
          `age` int(11) NOT NULL,                                                                                                                                                                                       
          `info` varchar(255) DEFAULT NULL,                                                                                                                                                                             
          KEY `MultiIdx` (`id`,`NAME`,`age`)                                                                                                                                                                            
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8        

由結果可以看到id,name,age字段上已經成功建立了一個名為MultiIdx的復合索引

 

我們向表插入兩條數據

INSERT INTO t3(id ,NAME,age,info) VALUES(1,'小明',12,'nihao'),(2,'小芳',16,'nihao')

使用EXPLAIN語句查看索引使用情況

EXPLAIN SELECT * FROM t3 WHERE id=1 AND NAME='小芳'

可以看到  possible_keyskey 為MultiIdx證明使用了復合索引

    id  select_type  table   type    possible_keys  key       key_len  ref            rows  Extra      
------  -----------  ------  ------  -------------  --------  -------  -----------  ------  -----------
     1  SIMPLE       t3      ref     MultiIdx       MultiIdx  94       const,const       1  Using where

如果我們只指定name而不指定id

EXPLAIN SELECT * FROM t3 WHERE  NAME='小芳'
    id  select_type  table   type    possible_keys  key     key_len  ref       rows  Extra      
------  -----------  ------  ------  -------------  ------  -------  ------  ------  -----------
     1  SIMPLE       t3      ALL     (NULL)         (NULL)  (NULL)   (NULL)       2  Using where

結果跟SQLSERVER一樣,也是不走索引, possible_keyskey都為NULL

 


全文索引

FULLTEXT索引可以用於全文搜索。只有MYISAM存儲引擎支持FULLTEXT索引,並且只支持CHAR、VARCHAR和TEXT類型

全文索引不支持過濾索引。

CREATE TABLE t4 (
  id INT NOT NULL,
  NAME CHAR(30) NOT NULL,
  age INT NOT NULL,
  info VARCHAR (255),
  FULLTEXT INDEX FulltxtIdx (info)
) ENGINE = MYISAM 

由於MYSQL5.6默認存儲引擎為InnoDB,這裡創建表的時候要修改表的存儲引擎為MYISAM,不然創建索引會出錯

SHOW CREATE TABLE t4 
Table   Create Table                                                                                                                                                                                                    
------  ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
t4      CREATE TABLE `t4` (                                                                                                                                                                                             
          `id` int(11) NOT NULL,                                                                                                                                                                                        
          `name` char(30) NOT NULL,                                                                                                                                                                                     
          `age` int(11) NOT NULL,                                                                                                                                                                                       
          `info` varchar(255) DEFAULT NULL,                                                                                                                                                                             
          FULLTEXT KEY `FulltxtIdx` (`info`)                                                                                                                                                                            
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8   

由結果可以看到,info字段上已經成功建立名為FulltxtIdx的FULLTEXT索引。

全文索引非常適合大型數據集合

 

在SQLSERVER裡使用全文索引比MYSQL還要復雜

詳細可以參考下面兩篇文章:

關於SQLSERVER的全文目錄跟全文索引的區別

[SQLSERVER]SQL中的全文檢索(轉鄒建)


空間索引

空間索引必須在 MYISAM類型的表中創建,而且空間類型的字段必須為非空

建表t5

CREATE TABLE t5
(g GEOMETRY NOT NULL ,SPATIAL INDEX spatIdx(g))ENGINE=MYISAM
SHOW CREATE TABLE t5

TABLE   CREATE TABLE                                                                                                   
------  ---------------------------------------------------------------------------------------------------------------
t5      CREATE TABLE `t5` (                                                                                            
          `g` GEOMETRY NOT NULL,                                                                                       
          SPATIAL KEY `spatIdx` (`g`)                                                                                  
        ) ENGINE=MYISAM DEFAULT CHARSET=utf8    

可以看到,t5表的g字段上創建了名稱為spatIdx的空間索引。注意創建時指定空間類型字段值的非空約束

並且表的存儲引擎為MYISAM


已經存在的表上創建索引

在已經存在的表中創建索引,可以使用ALTER TABLE或者CREATE INDEX語句

 

1、使用ALTER TABLE語句創建索引,語法如下

ALTER TABLE table_name ADD [UNIQUE|FULLTEXT|SPATIAL][INDEX|KEY]

[index_name](col_name[length],...)[ASC|DESC]

 

與創建表時創建索引的語法不同,在這裡使用了ALTER TABLE和ADD關鍵字,ADD表示向表中添加索引

在t1表中的name字段上建立NameIdx普通索引

ALTER TABLE t1 ADD INDEX NameIdx(NAME)

添加索引之後,使用SHOW INDEX語句查看指定表中創建的索引

SHOW INDEX FROM t1

TABLE   Non_unique  Key_name  Seq_in_index  Column_name  COLLATION  Cardinality  Sub_part  Packed  NULL    Index_type  COMMENT  Index_comment
------  ----------  --------  ------------  -----------  ---------  -----------  --------  ------  ------  ----------  -------  -------------
t1               0  UniqIdx              1  id           A                    0    (NULL)  (NULL)          BTREE                             
t1               1  NameIdx              1  NAME         A               (NULL)    (NULL)  (NULL)          BTREE         

各個參數的含義

1、TABLE:要創建索引的表

2、Non_unique:索引非唯一,1代表是非唯一索引,0代表唯一索引

3、Key_name:索引的名稱

4、Seq_in_index:該字段在索引中的位置,單列索引該值為1,復合索引為每個字段在索引定義中的順序

5、Column_name:定義索引的列字段

6、Sub_part:索引的長度

7、NULL:該字段是否能為空值

8、Index_type:索引類型

 

可以看到,t1表已經存在了一個唯一索引

 

在t3表的age和info字段上創建復合索引

ALTER TABLE t3 ADD INDEX t3AgeAndInfo(age,info)

使用SHOW INDEX查看表中的索引

SHOW INDEX FROM t3
Table   Non_unique  Key_name      Seq_in_index  Column_name  Collation  Cardinality  Sub_part  Packed  Null    Index_type  Comment  Index_comment
------  ----------  ------------  ------------  -----------  ---------  -----------  --------  ------  ------  ----------  -------  -------------
t3               1  MultiIdx                 1  id           A               (NULL)    (NULL)  (NULL)          BTREE                             
t3               1  MultiIdx                 2  NAME         A               (NULL)    (NULL)  (NULL)          BTREE                             
t3               1  MultiIdx                 3  age          A               (NULL)    (NULL)  (NULL)          BTREE                             
t3               1  t3AgeAndInfo             1  age          A               (NULL)    (NULL)  (NULL)          BTREE                             
t3               1  t3AgeAndInfo             2  info         A               (NULL)    (NULL)  (NULL)  YES     BTREE             

可以看到表中的字段的順序,第一個位置是age,第二個位置是info,info字段是可空字段

 

 

創建表t6,在t6表上創建全文索引

CREATE TABLE t6
(
  id INT NOT NULL,
  info CHAR(255)
)ENGINE= MYISAM;

注意修改ENGINE參數為MYISAM,MYSQL默認引擎InnoDB不支持全文索引

使用ALTER TABLE語句在info字段上創建全文索引

ALTER TABLE t6 ADD FULLTEXT INDEX infoFTIdx(info)

使用SHOW INDEX查看索引情況

SHOW INDEX FROM t6
Table   Non_unique  Key_name   Seq_in_index  Column_name  Collation  Cardinality  Sub_part  Packed  Null    Index_type  Comment  Index_comment
------  ----------  ---------  ------------  -----------  ---------  -----------  --------  ------  ------  ----------  -------  -------------
t6               1  infoFTIdx             1  info         (NULL)          (NULL)    (NULL)  (NULL)  YES     FULLTEXT                          

 

創建表t7,並在空間數據類型字段g上創建名稱為spatIdx的空間索引

CREATE TABLE t7(g GEOMETRY NOT NULL)ENGINE=MYISAM;

使用ALTER TABLE在表t7的g字段建立空間索引

ALTER TABLE t7 ADD SPATIAL INDEX spatIdx(g)

使用SHOW INDEX查看索引情況

SHOW INDEX FROM t7
Table   Non_unique  Key_name  Seq_in_index  Column_name  Collation  Cardinality  Sub_part  Packed  Null    Index_type  Comment  Index_comment
------  ----------  --------  ------------  -----------  ---------  -----------  --------  ------  ------  ----------  -------  -------------
t7               1  spatIdx              1  g            A               (NULL)        32  (NULL)          SPATIAL                           

 

 

2、使用CREATE INDEX語句創建索引,語法如下

CREATE [UNIQUE|FULLTEXT|SPATIAL]  INDEX index_name

ON table_name(col_name[length],...)  [ASC|DESC]

 

可以看到CREATE INDEX語句和ALTER INDEX語句的基本語法一樣,只是關鍵字不同。

我們建立一個book表

CREATE TABLE book (
  bookid INT NOT NULL,
  bookname VARCHAR (255) NOT NULL,
  AUTHORS VARCHAR (255) NOT NULL,
  info VARCHAR (255) NULL,
  COMMENT VARCHAR (255) NULL,
  year_publication YEAR NOT NULL
)

 

建立普通索引

CREATE INDEX BkNameIdx ON book(bookname)

 

建立唯一索引

CREATE UNIQUE INDEX UniqidIdx ON book(bookId)

 

建立復合索引

CREATE INDEX BkAuAndInfoIdx ON book(AUTHORS(20),info(50))

 

建立全文索引,我們drop掉t6表,重新建立t6表

DROP TABLE IF EXISTS t6

CREATE TABLE t6
(
  id INT NOT NULL,
  info CHAR(255)
)ENGINE= MYISAM;

CREATE FULLTEXT INDEX infoFTIdx ON t6(info);

 

建立空間索引,我們drop掉t7表,重新建立t7表

DROP TABLE IF EXISTS t7

CREATE TABLE t7(g GEOMETRY NOT NULL)ENGINE=MYISAM;

CREATE SPATIAL INDEX spatIdx  ON t7(g)

刪除索引

MYSQL中使用ALTER TABLE或者DROP INDEX語句來刪除索引,兩者實現相同功能

1、使用ALTER TABLE刪除索引

 語法

ALTER TABLE table_name DROP INDEX index_name

ALTER TABLE book DROP INDEX UniqidIdx
SHOW CREATE TABLE book
Table   Create Table                                                                                                                                                                                                                                                                                                                                                      
------  ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
book    CREATE TABLE `book` (                                                                                                                                                                                                                                                                                                                                             
          `bookid` int(11) NOT NULL,                                                                                                                                                                                                                                                                                                                                      
          `bookname` varchar(255) NOT NULL,                                                                                                                                                                                                                                                                                                                               
          `authors` varchar(255) NOT NULL,                                                                                                                                                                                                                                                                                                                                
          `info` varchar(255) DEFAULT NULL,                                                                                                                                                                                                                                                                                                                               
          `comment` varchar(255) DEFAULT NULL,                                                                                                                                                                                                                                                                                                                            
          `year_publication` year(4) NOT NULL,                                                                                                                                                                                                                                                                                                                            
          KEY `BkNameIdx` (`bookname`),                                                                                                                                                                                                                                                                                                                                   
          KEY `BkAuAndInfoIdx` (`authors`(20),`info`(50))                                                                                                                                                                                                                                                                                                                 
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8       

可以看到,book表中已經沒有名為UniqidIdx的唯一索引,刪除索引成功

 

注意:AUTO_INCREMENT約束字段的唯一索引不能被刪除!!

 

2、使用DROP INDEX 語句刪除索引

DROP INDEX index_name ON table_name

DROP INDEX BkAuAndInfoIdx ON book
SHOW CREATE TABLE book;

Table   Create Table                                                                                                                                                                                                                                                                                                   
------  ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
book    CREATE TABLE `book` (                                                                                                                                                                                                                                                                                          
          `bookid` int(11) NOT NULL,                                                                                                                                                                                                                                                                                   
          `bookname` varchar(255) NOT NULL,                                                                                                                                                                                                                                                                            
          `authors` varchar(255) NOT NULL,                                                                                                                                                                                                                                                                             
          `info` varchar(255) DEFAULT NULL,                                                                                                                                                                                                                                                                            
          `comment` varchar(255) DEFAULT NULL,                                                                                                                                                                                                                                                                         
          `year_publication` year(4) NOT NULL,                                                                                                                                                                                                                                                                         
          KEY `BkNameIdx` (`bookname`)                                                                                                                                                                                                                                                                                 
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8  

可以看到,復合索引BkAuAndInfoIdx已經被刪除了

 

提示:刪除表中的某列時,如果要刪除的列為索引的組成部分,則該列也會從索引中刪除。

如果索引中的所有列都被刪除,則整個索引將被刪除!!


總結

這一節介紹了MYSQL中的索引,索引語句的創建和刪除和一些簡單用法,希望對大家有幫助

 

如有不對的地方,歡迎大家拍磚o(∩_∩)o 

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