1.索引
    作用:
        - 約束
        - 加速查找
    索引分類(約束):
        - 普通索引:加速查找
        - 主鍵索引:加速查找 + 不能為空 + 不能重複
        - 唯一索引:加速查找 + 不能重複
        - 聯合索引(多列) :
            - 聯合主鍵索引
            - 聯合唯一索引
            - 聯合普通索引

   索引分類(加速查找):
            hash索引:
                索引表存儲(哈希值的順序和數據表中的數據順序不相同):
                    1.所有索引列數據轉換成的哈希值
                    2.索引列數據的內存地址
                hash索引優點:
                    查找單個值快
                    查找範圍值慢
            btree索引:二叉樹(innodb)
                二叉樹存儲:
                    先將索引列數據轉化成數字,每個二叉樹節點存儲一個數字及索引列數據的地址,
                    二叉樹節點的數字與子節點的數字有順序關係(左子節點數字小於父節點,有子節點數字大於父節點)
                hash索引優點:
                    查找單個值慢
                    查找範圍值快

 建立索引:
- a.額外的文件保存特殊的數據結構
        - b.查詢加快,插入更新刪除相對也會變慢
        - c.命中索引(此處email列建立了索引)
            select * from userinfo where email = 'asdf';
            # 由於未命中索引,查詢速度慢
            select * from userinfo where email like 'asdf';
        普通索引:
        - create index 索引名稱 on 表名(列名)
        - drop index 索引名稱 on 表名
        唯一索引:
        - create unique index 索引名稱 on 表名(列名)
        - drop unique index 索引名稱 on 表名
        組合(唯一)索引:
        - create unique index 索引名稱 on 表名(列名,列名)
        - drop index 索引名稱 on 表名
        - create unique index ix on userinfo3(name,email);
        - 最左前綴匹配(組合索引(name,email))
            select * from userinfo3 where name='alex';
            select * from userinfo3 where name='alex' and email='asdfg';
            # 無法使用索引,組合索引會優先匹配組合中左邊的列
            select * from userinfo3 where email='asdfg';
            組合索引效率>索引合併
        名詞:
            覆蓋索引:
                - 在索引文件中直接獲取數據(此處sid是索引)
                select sid from userinfo where sid = 5;
            索引合併:
                - 把多個單列索引合併使用,對多列單獨建立索引一起使用
                select * from userinfo3 where name='alex' and email='asdfg';

        部分索引(text類的使用短索引):
            create index ix__ on tb1(title(15)) 表示對title列前15個字符進行索引
2.不能命中索引情況:
- like '%xx'
            # name是索引,但是使用like和通配符進行查找,不能命中索引
            select * from tb1 where name like '%cn';
        - 使用函數
            # email是索引,但是使用reverse函數後不會命中索引
            select * from tb1 where reverse(email) = 'alex155@163.com';
        - or(僅當or中沒有建立索引的列才會不使用索引)
            # nid是索引 name不是索引 email是索引
            select * from tb1 where nid = 1 or name = 'alex';
            # 以下會走索引
            select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'alex'
        - 類型不一致(主鍵除外)
            # nid int類型,name是varcha類型
            select * from tb1 where nid = 1 or name = 888;
        - !=(主鍵除外)
            # name是索引,使用!=不能命中索引
            select * from tb1 where name != 'alex';
        - >(主鍵和整數類型除外)
            # name是索引,使用>不能命中索引
            select * from tb1 where name >'alex';
        - order by(主鍵除外)
            # 當根據索引排序時候,選擇的映射如果不是索引,則不走索引
            select name from tb1 order by email desc;
3.其他注意事項(不同的數據庫情況不同)
    - 避免使用select *
    - count(1)或count(列) 代替 count(*)
    - 創建表時儘量時 char 代替 varchar
    - 表的字段順序固定長度的字段優先
    - 組合索引代替多個單列索引(經常使用多個條件查詢時)
    - 儘量使用短索引
    - 使用連接(JOIN)來代替子查詢(Sub-Queries)
    - 連表時注意條件類型需一致
    - 索引散列值(重複少)不適合建索引,例:性別不適合

4.時間
 執行計劃(explain):讓mysql預估執行操作
    查詢時的訪問方式:
    性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
慢:
        explain select * from userinfo3 where name = 'alex'
        type = all(全表掃描)
    快:
        explain select * from userinfo3 where email = 'alex'
        type = ref(索引查找)
5.DBA工作
   慢日誌
        - 執行時間 >10
        - 未命中索引
        - 日誌文件路徑

    配置
        - 在內存中設置
# 查詢變量
            show variables like '%query%'
            show variables like '%queries%'
            # 打開慢查詢日誌
            set global slow_query_log = ON
            # 記錄沒有使用索引的SQL
            set global log_queries_not_using_indexes = ON
# 設置慢日誌文件存儲地址
        set slow_query_log_file = D:/....
- 在配置文件中設置(啓動客户達端時可以指定配置文件的地址)
          注意:修改配置文件之後,需要重啓服務
mysqld --defaults-file = 'D:\my.conf'
            my.conf中添加內容:
          # 打開慢查詢日誌  
                slow_query_log = ON

          # 記錄沒有使用索引的SQL
          set global log_queries_not_using_indexes = ON
# 設置慢日誌文件存儲地址
           slow_query_log_file = D:/....
6.分頁(基於數據庫實現類似網頁中的分頁功能)
 問題:同時對大量的數據進行分頁會浪費很多時間
    方案一:只給用户看到若干頁面
        缺點:這樣不能在根本上解決問題
    方案二:索引表
    缺點:在索引中掃描比在數據表中速度快,但是實際上不能加快很多,本質上還得掃描200000條數據
select * from userinfo3 where id in(select id from userinfo3 limit 200000,10);
方案三:記錄當前頁
        (id不一定連續,所以無法直接使用id範圍進行查找)
1.頁面只有上一頁,下一頁
            # max_id 當前頁面的最大id
            # min_id 當前頁面的最小id
            下一頁
            select * from userinfo3 where id > max_id limit 10;
            上一頁
            select * from userinfo3 where id < max_id  order by desc limit 10;
        2.上一頁 192 193 196 197 198 199 x下一頁
            # 當前處於193頁,需要跳到196頁
            select * from userinfo3 where id in (
            select id from (select * from userinfo3 where id > max_id limit 30) as N order by N.id desc limit 10;
            )