MySQL筆記(3)-- SQL分析

  • Linux服務器安裝MySQL後,直接命令mysql進入服務,需進行修改:
    /usr/bin/mysqladmin -u root password 123456
  • 設置開機自啓動:html

    chkconfig mysql on ---設置開機自啓動mysql
    chkconfig --list|grep mysql --查看mysql的運行級別  
    ntsysv --看到[*]mysql這一行,表示開機後自動啓動mysql
  • MySQL客戶端和服務器編碼格式默認使用latin1,致使插入中文亂碼,配置文件my.cnf進行修改字符集:
    [client]節點下面添加:
        default-character-set=utf8
    [mysqld]節點下面添加: 
        character_set_server=utf8
        character_set_client=utf8
        collation-server=utf8_general_ci
    [mysql]節點下面添加:
         default-character-set=utf8
  • MySQL主要配置文件信息:
    • 二進制日誌log-bin:主要用於主從複製;
    • 錯誤日誌log-error:默認關閉,記錄嚴重的警告和錯誤信息,每次啓動和關閉的詳細信息等;
    • 查詢日誌log:默認關閉,記錄查詢的sql語句,若是開啓會下降MySQL的總體性能;
    • 數據文件【每一個庫對應在磁盤中有下面文件】:
      • frm文件:存放表結構;
      • myd文件:存放表數據;
      • myi文件:存放表索引;
  • SQL執行加載順序:
    手寫:
        select distinct 列表
        form 表
        鏈接類型 join 表2
        on 鏈接條件
        where 篩選條件
        group by 分組列表
        having 分組後的篩選
        order by 排序列表
        limit 偏移,條目數
    機讀:
        from 表
        on 鏈接條件
        鏈接類型 join 表2
        where 篩選條件
        group by 分組列表
        having 分組後的篩選
        select distinct 列表
        order by 排序列表
        limit 偏移,條目數
    

  • 7種join:
    • 內鏈接,共有部分:select A.*,B.* from A inner join B on A.id=B.id;
    • 左鏈接:
      • 共有部分+右表沒有的匹配補null:select A.*,B.* from A left join B on A.id = B.id;【若創建索引進行SQL優化,需對右表B出現的字段創建索引,由於left join條件用於肯定如何從右表搜索行,左邊必定都有】
      • 左表獨有:select A.*,B.* from A left join B on A.id = B.id where B.id is null;
    • 右鏈接:
      • 共有部分+左表沒有的匹配補null:select A.*,B.* from A right join B on A.id = B.id;【若創建索引進行SQL優化,需對左表A出現的字段創建索引,由於right join條件用於肯定如何從左表搜索行,右邊必定都有】
      • 左表獨有:select A.*,B.* from A right join B on A.id = B.id where A.id is null;
    • 全鏈接union:
      • 合併去重,全鏈接:select A.*,B.* from A left join B on A.id = B.id union select A.*,B.* from A right join B on A.id = B.id;
      • 左右表獨有:select A.*,B.* from A left join B on A.id = B.id where B.id is null union select A.*,B.* from A right join B on A.id = B.id where A.id is null;
  • 索引:
    • 優點:提升數據檢索的效率,下降數據庫的IO成本;經過索引列對數據進行排序,下降數據排序的成本,下降了CPU的消耗。
    • 劣勢:索引是一張表,該表保存了主鍵和索引字段,並指向實體表的記錄,因此索引列是要佔用空間的;索引提升了查找速度,但下降了更新速度,對錶進行insert、update、delete時,MySQL不只要保存數據,還要保存索引文件每次更新添加 了索引列的字段,調整更新帶來的鍵值變化後的信息。
    • 分類:
      • 單值索引:一個索引只有一個列,一個表能夠有多個單值索引;
      • 惟一索引:索引列的值必須惟一,但能夠有null值;
      • 複合索引:一個索引包含多個列;
    • BTree索引原理
    • 索引建立的狀況:
      • 主鍵自動創建惟一索引;
      • 頻繁做爲查詢條件的字段;
      • 查詢中與其餘表關聯的字段,外鍵關係創建索引;
      • 查詢中排序的字段,排序字段若經過索引去訪問將大大提升排序速度【索引加快檢索和排序速度】;
      • 查詢中統計或分組字段;【分組與排序配合使用,分組前必須排序】
      • 高併發下傾向建立組合索引;
      • 頻繁更新的字段不適合建立索引;【須要更新索引信息】
      • where條件裏用不到的字段不建立索引;
      • 字段存儲的值重複,該字段不適合建立索引;
  • explain,分析查詢語句和表機構性能瓶頸:explain+查詢SQL
    • 做用:查看錶的讀取順序【id】;數據讀取操做的操做類型【select_type】;哪些索引可使用【possible_key】;哪些索引實際被使用【key】;表之間的引用【ref】;每張表有多少行被優化器查詢【rows】;
    • 查看執行計劃包含的信息
      •  id:select查詢的序列號,包含一組數字,表示查詢中執行select子句或操做表的順序【id爲null,最後執行】mysql

        • id相同,執行順序從上到下
        • id不一樣,若是是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行
        • id相同不一樣,同時存在:id若是相同,能夠認爲是一組,從上到下順序執行;在全部組中,id值越大,優先級越高,越先被執行;【衍生=DERIVED】
      • select_type:查詢的類型,主要是用於區分普通查詢、聯合查詢、子查詢等複雜查詢算法

        • SIMPLE:簡單的select查詢,查詢中不包含子查詢或UNION;
        • PRIMARY:查詢中若包含任何複雜的子部分,最外層查詢則爲PRIMARY;【select *from A where id =(select id from B)中A表爲PRIMARY】
        • SUBQUERY:在select或where列表中包含了子查詢;
        • DERIVED:在from列表中包含的子查詢爲DERIVED(衍生),MySQL會遞歸執行這些子查詢,把結果放在臨時表裏;
        • UNION:若第二個select出如今union以後,則被標記爲UNION;若UNION包含在from子句的子查詢中,外層select被標記爲DERIVED;【分析前面7種join中的合併去重,全鏈接sql】
        • UNION RESULT:從UNION表獲取結果的select;
      • table:顯示這一行的數據是關於哪張表的;sql

      • type:訪問類型【all、index、range、ref、eq_ref、const、system、NULL】,顯示查詢使用了何種類型,從最好到最差依次是system>const>eq_ref>ref>range>index>all數據庫

        • system:表只有一行記錄,等於系統表;
        • const:表示經過索引一次就找到了,const用於比較primary key或unique索引;由於只匹配一行數據,因此很快;如將主鍵置於where條件中,MySQL就能將該查詢轉換爲一個常量;
        • eq_ref:惟一性索引掃描,對於每一個索引鍵,表中只有一條記錄與之匹配,常見於主鍵或惟一索引掃描;【由t2進行驅動查找】
        • ref:非惟一性索引掃描,本質是一種索引訪問,它返回全部匹配某個單獨值的行,然而,它可能會找到多個符合條件的行,因此應該屬於查找和掃描的混合體
        • range:只檢索給定範圍的行,使用一個索引來進行;通常在where條件中出現了between、<、>、in等的查詢;這種範圍掃描索引比全表掃描要好,由於它只須要開始於索引的某一點,結束於另外一點,不用掃描所有索引;【若是索引字段是a,b,c,條件中使用了a的值是常量,b是範圍,對c進行排序,會致使索引失效】【優化:對範圍的字段從索引列中刪除,即覆蓋索引a,b,c改成a,c,從而變成ref級別】
        • index:Full Index Scan全索引掃描,index與all區別爲index類型只遍歷索引樹;一般比all快,由於索引文件一般比數據文件小;【all和index都是讀全表,但index是從索引中讀取,all是從磁盤中讀取】
        • all:全表掃描,遍歷全表查找符合的數據行;
      • possible_keys:顯示能夠應用在這張表中索引,一個或多個;查詢涉及到的字段上若存在索引,則該索引將被列出,但不必定被查詢實際使用;緩存

      • key:實際使用的索引,若是沒null【進行全表掃描】,則沒有使用索引;查詢中若使用了覆蓋索引,則該索引僅出如今key列表中【查詢的字段個數、順序與索引一一對應】;服務器

      • key_len:表示索引中使用的字節數,可經過該列計算查詢中使用的索引的長度;在不損失精確性的狀況下,長度越短越好;key_len顯示的值爲索引字段的最大可能長度,並不是實際使用長度,即key_len是根據表定義計算而得,不是經過表內檢索出的;數據結構

      • ref:顯示索引的哪一列被使用了【庫名.表名,被使用列名】,若是可能的話,是一個常數【const】;哪些列或常量被用於查找索引列上的值;併發

      • rows:根據表統計信息及索引選用狀況,大體估算出找到所需記錄所須要讀取的行數;高併發

      • extra::包含不適合在其餘列中顯示但十分重要的額外信息

        • Using filesort:說明MySQL會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取【建立了一個組合索引包含a,b,c,但在where條件和order by排序時,只使用了a,c,致使這個索引出現了斷層,會出現文件排序】;MySQL中沒法利用索引完成的排序操做稱爲「文件排序」;
        • Using temporary:使用了臨時表保存中間結果,MySQL在對查詢結果進行排序時使用臨時表,常見於排序order by和分組查詢group by;【臨時表增長數據庫負擔】
        • Using index:表示相應的select操做中使用了覆蓋索引【覆蓋索引:建立的索引包含a,b,進行select查詢的列全包含或部分包含如a,b或a】,避免訪問了表的數據行,效率不錯;若是同時出現using where,代表索引被用來執行索引鍵值的查找;若是沒有同時出現using where,代表索引用來讀取數據而非執行查找動做;
        • Using where:代表使用了where過濾;
        • using join buffer:使用了鏈接緩存;【出如今多表的inner join內鏈接中】【最好在my.cnf配置文件中的緩存調大點】
        • impossible where: where子句的值老是false,不能用來獲取任何元組;
        • select tables optimized away:在沒有group by子句的狀況下,基於索引優化MIN/MAX操做或對於MyISAM存儲引擎優化count(*)操做,沒必要等到執行階段再進行計算,查詢執行計劃生成的階段即完成優化;
        • distinct:優化distinct操做,在找到第一匹配的元組後即中止找一樣值的動做;
相關文章
相關標籤/搜索