Mysql sql語句技巧與優化

Mysql sql語句技巧與優化

一、常見sql技巧

  1、正則表達式的使用

    

  2、巧用RAND()提取隨機行

      mysql數據庫中有一個隨機函數rand()是獲取一個0-1之間的數,利用這個函數和order by一起能夠吧數據隨機排序,

、       mysql>select * from stu order by rand();

      下面是通過limit隨機抽取了3條數據樣本。

        mysql>select * from stu order by rand() limit 3;

  3、利用GROUP BY 的WITH ROLLUP子句統計

      使用group by的with rollup子句可以檢索出更多的聚合信息。

        mysql>select cname,pname,count(pname) from demo group by cname,pname;

        同樣使用with rollup關鍵字後,統計出更多的信息。注意:with rollup不可以和order by同時使用。

        mysql>select cname,pname,count(pname) from demo group by cname,pname with rollup;

  4、用BIT GROUP FUNCTIONS 做統計

      在使用group by語句時可以同時使用bit_anf、bit_or函數來完成統計工作,這兩個函數的主要作用是做數值之間的邏輯位運算。

        mysql>select id,bit_or(kind) from order_rab group by id;      //二進制位運算

        對order_rab表中id分組時對kind做位與和或計算。

        mysql>select id,bit_and(kind) from order_rab group by id;    //二進制餘運算,只有11才爲1

  5、使用外健要注意的問題

      創建外健如下:

        mysql>create table temp(id int,name char(20),foreign key(id) references outTable(id) on delete cascade on update cascade));

        注意:innodb類型的表支持外健,myisam類型的表,雖然創建可以成功,但不起作用,主要原因是不支持外健。

  6、mysql中help的使用

      a、?%可以獲得所有mysql>裏的命令,

      b、?create

      c、?opt%,因爲記不住全稱。

二、mysql的優化

  1、優化sql語句的一般步驟

      通過show status命令瞭解各種sql的執行頻率。

        格式:mysql>show [session|global] status;

          session:(默認)表示當前鏈接

          globla:表示自數據庫啓用至今

        如:mysql>show status;

          mysql>show global status;

          mysql>show status like "Com_%";

          mysql>show global status like "Com_%";

        參數說明:

          Com_select 執行select操作的次數,一次查詢值累計加1

          Com_update 執行update操作的次數

          Com_insert 執行insert操作的次數

          Com_delete 執行delete操作的次數

        只針對Innodb引擎的:

          InnoDB_rows_read執行select操作的次數

          InnoDB_rows_update執行update操作的次數

          InnoDB_rows_insert執行insert操作的次數

          InnoDB_rows_delete執行delete操作的次數

        其他:

          connections鏈接mysql的數量

          Uptime服務器已經工作的秒數

          Slow_queries慢查詢的次數

  2、定位執行效率較低的sql語句:

      a、explain select * from table where id = 1000;

      b、desc select * from table where id = 1000;

          

          

    c、優化的順序:

        1)查看慢查詢日誌,日誌裏查詢超過10秒的說明產尋幽問題

        2)通過desc定位這條語句哪裏有問題。

        3)通過方案對問題點進行優化,如加索引

  2、索引問題

      索引實數據庫優化中最常見的也是最重要的手段之一,通過索引通常可以幫助用戶姐絕大多數的sql性能問題。

      1)索引的存儲和分類:

          MyISAM存儲引擎的表的數據和索引是自動分開存儲的,各自是獨一的一個文件;InnoBDB存儲引擎的表的數據和索引是存儲在同一個表空間裏面,但可以由多個文件組成。

          mysql目前不支持函數索引,但是能對列的前面某一部分進行進行索引,例如name字段,可以去name的前2個字符進行索引,這個特性可以大大縮小文件的大小,用戶在設計表結構的時候也可以對文本列根據此特性進行靈活設計。

            mysql>create index ind_company2_name on company2(name(4));//company表名,ind_company2_name索引名

      2)mysql如何使用索引

          索引用於快速找出在某個列中有一特定值的行。對相關列使用索引是提高SELECT操作性能的最佳途徑。

          a、使用索引

            (1)對於創建的多行索引,只要查詢的條件中用到最左邊的列,索引一般就會被使用。如下創建一個複合索引。

                mysql>create index ind_sales2_com_mon onsales2(company_id,moneys);

              然後按company_id進行查詢,發現使用到了複合索引。

                mysql>explain select * from sales2 where company_id=2006\G;

              使用下面的查詢就沒有使用複合索引。

                mysql>explain select * from sales2 where moneys=1\G;

            (2)使用like的查詢,後面如果是常量並且只有%號不在第一個字符,索引纔可能被使用,如下:

                mysql>explan select * from company2 where name like "%3"\G;

                

        3)存在索引但不使用索引

            (1)如果mysql估計使用索引比全表掃描更慢,則不使用索引。例如如果列key_prat1均勻分佈在1-100之間,查詢時使用索引就不是很好

                mysql>select * from table_name where ley_part1>1 and key_part<90;

            (2)如果使用MEMORY/HEAP表並且where條件中不使用“=”進行索引列,那麼不會用到索引。Heap表只有在“=”的條件下使用索引。

            (3)用or分割的條件,如果or前的條件中的列有索引,二後面的列沒有索引,那麼涉及的索引都不會用到。

            (4)如果不是索引列的第一部分,如下例子:可見雖然在money上面建有複合索引,但是由於money不是索引的第一列,那麼在查詢中,這個索引也不會被mysql採用。

                mysql>explan select * from sales2 where moneys=1\G;

                

            (5)如果like是一%開始,可見雖然在name上家有索引,但是由於條件中的like的值的“%”在第一位了,那麼mysql也不會採用這個索引。

            (6)如果列類型是字符串,但在查詢時把第一個數值型常量賦值給了一個字符類型的列名name,那麼雖然在name列上有索引,但是也沒有用到。

                mysql>explain select * from company2 where name=294\G;

                

       4)查看索引的使用情況

          如果索引正在工作,Handler_read_key的值將很高,這個值代了一個行別索引值讀的次數。

          Handler_read_next的高則意味着查詢運行低效,並且應該建立索引補救。

          

 

  3、兩個簡單的優化方法

      對於多數開發人員來說,可能希望掌握一些簡單實用的優化方法,對於更堵更復雜的優化,更傾向於交給作業dba來做。

      1)定期分析表和檢查表

        ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tal_name[,tbl_name]....

          本語句用於分析和儲存表的關鍵字分佈,分析的結果將可以得到準確的統計信息,使得sql能夠生成正確的行計劃。

          

          

      2)定期優化表

          

  4、常用sql的優化

      1)大批量插入數據。

          當用load命令導入數據庫的時候,適當設置可以提高導入速度。

          對於myisam存儲引擎的表,可以通過以下方式快速的導入大量的數據。

            ALTER TABLE tbl_name DISABLE KEYS 

            loading the data

            ALTER TABLE tbl_name ENABLE KEYS

          DISABLE KEYS和ENABLE KEYS用來打開或關閉mysiam表非唯一索引的更新,可以提高速度。注意:對innodb表無效。

          

      2)關閉唯一性校驗可以提高導入效率。

          再倒入數據前限制性set unique_checks=0,關閉唯一性校驗,再倒入結束後執行set unique_checks=1,恢復唯一性校驗可以提高到付效率。

          

          

          

      3)優化insert語句

          及兩使用多個值表的insert語句,這樣可以大大算短客戶與數據庫的連接、關閉等損耗。

          可以使用insert delayed(馬上執行)語句得到更高的效率將索引文件和數據文件分別存放不同的磁盤上。

          可以增加bulk_buffer_size變量值的方法來提高速度,但是隻對myisam表使用。

          當一個文件裝載一個表時,使用LOAD DATA INFILE。這個通常比使用很多insert語句要快20唄。

      4)優化group bu語句

          如果查詢包含group by但用戶想要避免排序結果的損耗,則可以使用order by null來禁止排序:

          如下沒有使用order by null 來禁止排序。

          

      5)優化order by語句

          在某些情況中,mysql可以使用一個索引來滿足order by 子句,而不需要額外的排序。where條件和order by使用相同的索引,並且order by的順序和索引順序相同,並且order by的字段都是升序或者降序。

          

       6)優化嵌套查詢

          下面是採用嵌套查詢的效果(可以使用更有效的鏈接查詢(join)替代)

          explain select * from sales2 where company_id not in (select id from complany2)\G

          

          

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章