mysql 添加索引,ALTER TABLE和CREATE INDEX的區別


 

nvicat-->mysql表設計-->創建索引.

 

 

 

(1)使用ALTER TABLE語句創建索引,其中包括普通索引、UNIQUE索引和PRIMARY KEY索引3種創建索引的格式:

PRIMARY KEY 主鍵索引:mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 
NIQUE唯一索引:mysql>ALTER TABLE `table_name` ADD UNIQUE ( `column` ) 
INDEX普通索引 :mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) 
FULLTEXT全文索引 :mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column`) 
INDEX多列索引:mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )

索引名index_name可選,缺省時,MySQL將根據第一個索引列賦一個名稱。另外,ALTER TABLE允許在單個語句中更改多個表,因此可以同時創建多個索引。

 


(2)使用CREATE INDEX語句對表增加索引。
能夠增加普通索引和UNIQUE索引兩種。其格式如下:
create index index_name on table_name (column_list) ;
create unique index index_name on table_name (column_list) ;  #表中有primary Key后不能用uniq index。
說明:table_name、index_name和column_list具有與ALTER TABLE語句中相同的含義,索引名不可選。另外,不能用CREATE INDEX語句創建PRIMARY KEY索引。


(3)刪除索引。
刪除索引可以使用ALTER TABLE或DROP INDEX語句來實現。2881064151DROP INDEX可以在ALTER TABLE內部作為一條語句處理,其格式如下:
drop index index_name on table_name ;
alter table table_name drop index index_name ;
alter table table_name drop primary key ;
其中,在前面的兩條語句中,都刪除了table_name中的索引index_name。而在最后一條語句中,只在刪除PRIMARY KEY索引中使用,因為一個表只可能有一個PRIMARY KEY索引,因此不需要指定索引名。如果沒有創建PRIMARY KEY索引,但表具有一個或多個UNIQUE索引,則MySQL將刪除第一個UNIQUE索引。
如果從表中刪除某列,則索引會受影響。對於多列組合的索引,如果刪除其中的某列,則該列也會從索引中刪除。如果刪除組成索引的所有列,則整個索引將被刪除。
刪除索引的操作,如下面的代碼:
mysql> drop index shili on tpsc ;
Query OK, 2 rows affected (0.08 sec)
Records: 2 Duplicates: 0 Warnings: 0
該語句刪除了前面創建的名稱為“shili”的索引。

 

 

索引不一定是唯一所以,是可以加快查詢速度的。

立索引原則:“如何查就如何建”。

索引的建立,唯一的原目的就是為了加快查詢(廣義的查詢),實際上建立索引會使得數據存儲所占空間變大,有時索引所占的空間會查過數據本身的空間。索引的建立也會使得數據插入時變慢,特殊情況下,慢的難以忍受,所以DBA的重要工作之一,就是檢查索引層級並優化。

索引的目的就是希望盡可能的被索引的字段不重復,那么查找的效率就是1,如果完全重復,效率就是N,如果部分重復,那么效率會小於N,視重復量而定。mysql的索引算法是Btree。 

 

 

為什么重復值高的字段不能建索引(比如性別字段等) 

 

 結論(以innodb為例)

a、非聚簇索引存儲了對主鍵的引用,如果select字段不在非聚簇索引內,就需要跳到主鍵索引(上圖中從右邊的索引樹跳到左邊的索引樹),再獲取select字段值

b、如果非聚簇索引值重復率高,那么查詢時就會大量出現上圖中從右邊跳到左邊的情況,導致整個流程很慢

c、如果where值重復率高的字段,select用了limit,只查較少數據,也就是跳的次數很少的情況下,還是可以建索引的(后來想想也沒必要,limit限制了數量,全表掃描也很快,除非字段值是排序的,必須掃描完前面的所有值)

d、如果沒有3這個前提,則不建議在值重復率高的字段上建索引,因為查詢效率低,還需要維護索引

 

 

 

 

 

 

 

 

 

SQL有三個類型的索引,唯一索引 不能有重復,但聚集索引,非聚集索引可以有重復

重要:

(1) SQL如果創建時候,不指定類型那么默認是非聚集索引

(2) 聚集索引和非聚集索引都可以有重復記錄,唯一索引不能有重復記錄。

(3) 主鍵 默認是加了唯一約束的聚集索引,但是也可以在主鍵創建時,指定為唯一約束的非聚集索引,因此主鍵僅僅是默認加了唯一約束的聚集索引,不能說主鍵就是加了唯一約束的聚集索引

有點拗口,可以參考我的博客:主鍵就是聚集索引嗎?

為列創建索引實際上就是為列進行排序,以方便查詢.建立一個列的索引,就相當與建立一個列的排序。

    主鍵是唯一的,所以創建了一個主鍵的同時,也就這個字段創建了一個唯一的索引,

    唯一索引實際上就是要求指定的列中所有的數據必須不同。

    主鍵一唯一索引的區別:

         1 一個表的主鍵只能有一個,而唯一索引可以建多個。
         2 主鍵可以作為其它表的外鍵。
         3 主鍵不可為null,唯一索引可以為null。

聚集索引:將表內的數據按照一定的規則進行排列的目錄。正因為如此,一個表中的聚焦索引只有一個。對此我們要注意“主鍵就是聚焦索引”這是極端錯誤的,是對聚焦索引的一種浪費。(雖然SQLServer默認主鍵就是聚焦索引)使用聚焦索引的最大好處就是按照查詢要求,迅速縮小查詢范圍,避免進行全表掃描。其次讓每個數目都不相同的字段作為聚焦索引也不符合“大數目不同情況下不應建立聚集索引的原則”。

一、索引的作用

1、幫助檢索數據;

2、提高聯接效率;

3、節省ORDER BY、GROUP BY的時間;

4、保證數據唯一性(僅限於唯一索引)。

 

二、索引的設計

在確定要建立一個索引時,首先我們要確定它是聚集還是非聚集、單列還是多列、唯一還是非唯一、列是升序還是降序、它的存儲是如何的,比如:分區、填充因子等。下面逐條來看:

1、聚集索引

(1)首先指出一個誤區,主鍵並不一定是聚集索引,只是在SQL SERVER中,未明確指出的情況下,默認將主鍵定義為聚集,而Oracle中則默認是非聚集,因為SQL SERVER中的ROWID未開放使用。

(2)聚集索引適合用於需要進行范圍查找的列,因為聚集索引的葉子節點存放的是有序的數據行,查詢引擎可根據WHERE中給出的范圍,直接定位到兩端的葉子節點,將這部分節點頁的數據根據鏈表順序取出即可;

(3)聚集索引盡量建立在值不會發生變更的列上,否則會帶來非聚集索引的維護;

(4)盡量在建立非聚集索引之前建立聚集索引,否則會導致表上所有非聚集索引的重建;

(5)聚集索引應該避免建立在數值單調的列上,否則可能會造成IO的競爭,以及B樹的不平衡,從而導致數據庫系統頻繁的維護B樹的平衡性。聚集索引的列值最好能夠在表中均勻分布。

3、唯一索引

(1)再指出一個誤區,聚集索引並不一定是唯一索引,由於SQL SERVER將主鍵默認定義為聚集索引,事實上,索引是否唯一與是否聚集是不相關的,聚集索引可以是唯一索引,也可以是非唯一索引;

(2)將索引設置為唯一,對於等值查找是很有利的,當查到第一條符合條件的紀錄時即可停止查找,返回數據,而非唯一索引則要繼續查找,同樣,由於需要保證唯一性,每一行數據的插入都會去檢查重復性;

 

下面是一個簡單的比較表

 

 

  主鍵 聚集索引
用途 強制表的實體完整性 對數據行的排序,方便查詢用
一個表多少個 一個表最多一個主鍵 一個表最多一個聚集索引
是否允許多個字段來定義 一個主鍵可以多個字段來定義 一個索引可以多個字段來定義
     
是否允許 null 數據行出現 如果要創建的數據列中數據存在null,無法建立主鍵。
創建表時指定的 PRIMARY KEY 約束列隱式轉換為 NOT NULL。
沒有限制建立聚集索引的列一定必須 not null .
也就是可以列的數據是 null
參看最后一項比較
是否要求數據必須唯一 要求數據必須唯一 數據即可以唯一,也可以不唯一。看你定義這個索引的 UNIQUE 設置。
(這一點需要看后面的一個比較,雖然你的數據列可能不唯一,但是系統會替你產生一個你看不到的唯一列)
     
創建的邏輯 數據庫在創建主鍵同時,會自動建立一個唯一索引。
如果這個表之前沒有聚集索引,同時建立主鍵時候沒有強制指定使用非聚集索引,則建立主鍵時候,同時建立一個唯一的聚集索引
如果未使用 UNIQUE 屬性創建聚集索引,數據庫引擎 將向表自動添加一個四字節 uniqueifier 列。
必要時,數據庫引擎 將向行自動添加一個 uniqueifier 值,使每個鍵唯一。此列和列值供內部使用,用戶不能查看或訪問。
 

 

 

 

 

 

 

 

 

 

 

 

下面是更加詳細的方法

MySQL中可以使用alter table這個SQL語句來為表中的字段添加索引。

使用alter table語句來為表中的字段添加索引的基本語法是:
ALTER TABLE <表名> ADD INDEX (<字段>);

我們來嘗試為test中t_name字段添加一個索引。

mysql> alter table test add index(t_name);
Query OK, 0 rows affected (0.17 sec)
Records: 0  Duplicates: 0  Warnings: 0

執行成功后,我們來看看結果。

mysql> describe test;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| t_id       | int(11)     | YES  |     | NULL    |       |
| t_name     | varchar(50) | NO   | MUL | NULL    |       |
| t_password | char(32)    | YES  |     | NULL    |       |
| t_birth    | date        | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

結果可以看出,t_name字段的Key這一欄由原來的空白變成了MUL。這個MUL是什么意思呢?簡單解釋一下:如果Key是MUL,那么該列的值可以重復,該列是一個非唯一索引的前導列(第一列)或者是一個唯一性索引的組成部分但是可以含有空值NULL。


 

 

 

 

MySQL創建索引方法:ALTER TABLE和CREATE INDEX的區別

眾所周知,MySQL創建索引有兩種語法,即:
ALTER TABLE HeadOfState ADD INDEX (LastName, FirstName);
CREATE INDEX index_name HeadOfState (LastName, FirstName);
那么,這兩種語法有什么區別呢? :wink:
在網上找了一下,在一個英文網站上,總結了下面幾個區別,我翻譯出來,如下:
1、CREATE INDEX必須提供索引名,對於ALTER TABLE,將會自動創建,如果你不提供;
2、CREATE INDEX一個語句一次只能建立一個索引,ALTER TABLE可以在一個語句建立多個,如:
      ALTER TABLE HeadOfState ADD PRIMARY KEY (ID), ADD INDEX (LastName,FirstName);
3、只有ALTER TABLE 才能創建主鍵,

英文原句如下:
With CREATE INDEX, we must provide a name for the index. With ALTER TABLE, MySQL creates an index name automatically if you don’t provide one.Unlike ALTER TABLE, the CREATE INDEX statement can create only a single index per statement. In addition, only ALTER TABLE supports the use of PRIMARY KEY.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM