1. 程式人生 > >mysql 的索引操作

mysql 的索引操作

"""
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可以;

"""

# 單列索引(普通索引,唯一索引,主鍵索引)、 組合索引、 全文索引、 空間索引。  後兩個用到的時候在說,前兩個一定要記住

"""
注意 : 一個表只有一個主鍵,不存在刪除某一列的主鍵,主鍵是唯一的
"""