mysql 的索引操作
阿新 • • 發佈:2018-11-30
""" MySQL中的索引的儲存型別有兩種:BTREE、HASH SHOW INDEX FROM 表名\G; 顯示錶裡面所有的索引值 """ """ 一 、 索引的優、缺點以及使用原則 優點: 1、查詢某條資料的時候,不用在遍歷整個表,提高效率。 2、所有的MySql列型別(欄位型別)都可以被索引,也就是可以給任意欄位設定索引 3、大大加快資料的查詢速度 缺點: 1、建立索引和維護索引要耗費時間,並且隨著資料量的增加所耗費的時間也會增加 2、索引也需要佔空間,我們知道資料表中的資料也會有最大上限設定的,如果我們有大量的索引,索引檔案可能會比資料檔案更快達到上限值 3、當對錶中的資料進行增加、刪除、修改時,索引也需要動態的維護,降低了資料的維護速度。 使用原則: 通過上面說的優點和缺點,我們應該可以知道,並不是每個欄位都設定索引就好,也不是索引越多越好,而是需要自己合理的使用。 1、對經常更新的表就避免對其進行過多的索引,對經常用於查詢的欄位應該建立索引。 2、資料量小的表最好不要使用索引,因為由於資料較少,可能查詢全部資料花費的時間比遍歷索引的時間還要短,索引就可能不會產生優化效果。 3、在一同值少的列上(欄位上)不要建立索引,比如在學生表的"性別"欄位上只有男,女兩個不同值。相反的,在一個欄位上不同值較多可是建立索引。 """ """ 二、索引的分類 注意:索引是在儲存引擎中實現的,也就是說不同的儲存引擎,會使用不同的索引 MyISAM和InnoDB儲存引擎:只支援BTREE索引, 也就是說預設使用BTREE,不能夠更換 MEMORY/HEAP儲存引擎:支援HASH和BTREE索引 1、索引我們分為四類來講 單列索引(普通索引,唯一索引,主鍵索引),組合索引,全文索引,空間索引 1.1、單列索引:一個索引只包含單個列,但一個表中可以有多個單列索引。 這裡不要搞混淆了。 1.1.1、普通索引: MySQL中基本索引型別,沒有什麼限制,允許在定義索引的列中插入重複值和空值,純粹為了查詢資料更快一點。 1.1.2、唯一索引: 索引列中的值必須是唯一的,但是允許為空值 1.1.3、主鍵索引: 是一種特殊的唯一索引,不允許有空值 1.2、組合索引: 在表中的多個欄位組合上建立的索引,只有在查詢條件中使用了這些欄位的左邊欄位時,索引才會被使用,使用組合索引時遵循最左字首集合。 這個如果還不明白,等後面舉例講解時在細說。 1.3、全文索引 MyISAM引擎 全文索引,只有在 MyISAM引擎 上才能使用,只能在 CHAR,VARCHAR,TEXT 型別欄位上使用全文索引,介紹了要求,說說什麼是全文索引,就是在一堆文字中,通過其中 的某個關鍵字等,就能找到該欄位所屬的記錄行,比如有"你是個大煞筆,二貨 ..." 通過大煞筆,可能就可以找到該條記錄。這裡說的是可能,因為全文索引的使用 涉及了很多細節,我們只需要知道這個大概意思,如果感興趣進一步深入使用它,那麼看下面測試該索引時,會給出一個博文,供大家參考. 1.4、空間索引 MyISAM引擎 空間索引是對空間資料型別的欄位建立的索引,MySQL中的空間資料型別有四種,GEOMETRY、POINT、LINESTRING、POLYGON。 在建立空間索引時,使用SPATIAL關鍵字。 要求,引擎為MyISAM,建立空間索引的列,必須將其宣告為NOT NULL。具體細節看下面 """ """ 建立普通索引: 唯一 全文 空間 語法: create table tablename [UNIQUE|FULLTEXT|SPATIAL|...]([欄位1,欄位型別1,欄位2,欄位型別2 .....] index | key (欄位名稱)[ASC|DESC] ) 如果你選取的欄位是普通欄位,那麼即則是普通索引 CREATE TABLE c( id INT(11) NOT NULL auto_increment, name VARCHAR(10) NULL, age TINYINT(3) NULL, KEY id3 (id) ) -- 注意 : 可以給索引起別名,比如說這裡面的 id3 就是別名 -- 如果不起別名,那麼欄位名就是索引名。 CREATE TABLE `a` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(10) DEFAULT NULL, `age` tinyint(3) DEFAULT NULL, INDEX `id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- INSERT INTO a (NAME,age) VALUES("haha",6),("cc",8),("aa",10) ; SELECT * from a ; EXPLAIN SELECT * from a WHERE id=2; # 這個就是 id 索引,這裡面查詢根據索引值進行查詢,速度會很快 EXPLAIN SELECT * from a WHERE age=6; # age 不是索引,獲取資料的時候要遍歷整個表裡面的資料 INSERT INTO b (NAME,age) VALUES("haha",6),("cc",8),("aa",10) ; EXPLAIN SELECT * from b WHERE id=2; EXPLAIN SELECT * from b WHERE age=6; INSERT INTO c (NAME,age) VALUES("haha",6),("cc",8),("aa",10) ; EXPLAIN SELECT * from c WHERE id=2; EXPLAIN SELECT * from c WHERE age=6; """ """ 建立唯一索引: -- 建立唯一索引 UNIQUE INDEX|KEY 索引別名 (欄位名稱) CREATE TABLE t( id INT(11) NOT NULL, name CHAR(30), UNIQUE INDEX unique_id(id) ); CREATE TABLE `t` ( `id` int(11) NOT NULL, `name` char(30) DEFAULT NULL, UNIQUE KEY `unique_id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 插入資料: -- INSERT INTO t (id,NAME) VALUES (1,"aa"),(2,"bb"),(3,"cc"); -- INSERT INTO t (id,NAME) VALUES (4,"aa") -- INSERT INTO t (id,NAME) VALUES (4,"ee") # 這句話會報錯,因為我們已經建立了 id 唯一索引,id值不能重複,其他值可以重複 EXPLAIN SELECT * FROM t WHERE id=1; """ """ 建立主鍵索引: -- 建立主鍵索引 CREATE TABLE t3( id INT(11) NOT NULL , name CHAR(30) NOT NULL, PRIMARY KEY (id) ) CREATE TABLE t2( id INT(11) NOT NULL, name CHAR(30) NULL, PRIMARY KEY(id) ); -- 主鍵索引 id 作為索引,主鍵索引是特殊的唯一索引,索引值 CREATE TABLE `t2` ( `id` int(11) NOT NULL, `name` char(30) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO t2 VALUES(1,'aaa'),(2,"bbb"); SELECT * FROM t2; EXPLAIN SELECT * FROM t2 WHERE id = 1; """ """ 建立 組合索引: -- 建立組合索引 -- 組合索引就是在多個欄位上建立一個索引 -- 比如說:建立一個表t3,在表中的id、name和age欄位上建立組合索引 # drop TABLE IF NOT EXISTS `haha` 格式 : drop table if exists 表名 DROP TABLE if EXISTS t3; CREATE TABLE t3( id INT(11) NOT NULL, NAME CHAR(30) NOT NULL, age INT(3) NULL, info VARCHAR(255), INDEX (id,name,age) ) -- DDL語句 : CREATE TABLE `t4` ( `id` int(11) NOT NULL, `NAME` char(30) NOT NULL, `age` int(3) DEFAULT NULL, `info` varchar(255) DEFAULT NULL, KEY `id` (`id`,`NAME`,`age`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 表 t3 沒有給組合索引命名,預設為第一個值 id 就是索引的別名 DROP TABLE if EXISTS t4; CREATE TABLE t4( id INT(11) NOT NULL, NAME CHAR(30) NOT NULL, age INT(3) NULL, info VARCHAR(255), INDEX MultiIdx (id,name,age) ) -- 表 t4 組合索引的別名為 MultiIdx 資料庫查詢的時候按照最左索引的方法來查詢。 比如說: 這裡面是(id,name,age)按照索引查必須欄位 必須是(id),(id,name),(id,name,age),否則的話不按照索引 來查,還是會遍歷表,不根據索引查詢. INSERT INTO t4 (id,NAME,age,info) VALUES(1,"a",10,"aa"),(2,"b",20,"bb"); SELECT * from t4; EXPLAIN SELECT * FROM t4 WHERE id=1; # 按照索引進行查詢 EXPLAIN SELECT * FROM t4 WHERE id=1 AND name="a"; # 按照索引進行查詢 EXPLAIN SELECT * FROM t4 WHERE name="a" AND age=10; # 遍歷表t4 組合索引就是多個欄位的索引值。 """ """ 新增索引: 第一種方式: 修改表結構來新增索引 alter table a add index index_name(欄位名稱) egg: ALTER TABLE book ADD INDEX BkNameIdx(bookname(30)); 第二種方式: 使用CREATE INDEX建立索引 格式:CREATE [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] 索引名稱 ON 表名(建立索引的欄位名[length])[ASC|DESC] CREATE INDEX BkBookNameIdx ON book(bookname); egg : create index index_name on t4(欄位名稱) create index cc on field_name # 建立索引 alter table table_name add index cc (field_name) # 新增索引 alter 語句 """ """ 刪除索引: 刪除book表中名為BkNameIdx的索引 格式一:ALTER TABLE 表名 DROP INDEX 索引名。 ALTER TABLE book DROP INDEX BkBookNameIdx; egg: alter table t4 drop index (索引名稱) alter table t4 drop index (索引名稱) 格式二:DROP INDEX 索引名 ON 表名; DROP INDEX BkNameIdx ON book; egg: drop index (索引名稱) on t4; drop index (索引名稱) on 表名 """ """ 十二、全文檢索——MATCH和AGAINST 1、SELECT MATCH(note_text)AGAINST('PICASO') FROM tb_name; 2、InnoDB引擎不支援全文檢索,MyISAM可以; """ # 單列索引(普通索引,唯一索引,主鍵索引)、 組合索引、 全文索引、 空間索引。 後兩個用到的時候在說,前兩個一定要記住 """ 注意 : 一個表只有一個主鍵,不存在刪除某一列的主鍵,主鍵是唯一的 """