1. 程式人生 > >SQL語句優化大全

SQL語句優化大全

一、定位慢查詢: 必要指令: show status like ‘uptime’;當前資料庫執行多久

show session或global status like ‘com_select’;當前資料庫執行多少次查詢 show session或global status like ‘com_update’;當前資料庫執行多少次更新 show session或global status like ‘com_delete’;當前資料庫執行多少次刪除 show session或global status like 'com_insert;當前資料庫執行多少次查詢 預設是session,意思是當前會話的操作次數 global是所有的操作次數 根據資料庫的操作型別來決定使用什麼儲存引擎

show status like ‘connections’;當有多少客戶端連線資料庫

show status like ‘slow_queries’;查詢有多少慢查詢

預設情況,mysql認為查詢時間到達10秒才是一個慢查詢 show variables like ‘long_query_time’;顯示慢查詢定義時間 set long_query_time=1;將慢查詢定義時間設定為1秒 查詢方法: 1.停止mysql服務,在計算機管理–>服務–>mysql中停止 2.在預設情況下mysql不記錄慢查詢日誌,需要在啟動的時候指定 bin\mysqld.exe - -safe-mode - -slow-query-log [mysql5.5 可以在my.ini指定] bin\mysqld.exe –log-slow-queries=d:/abc.log [低版本mysql5.0可以在my.ini指定] (在bin的上級目錄開啟cmd再執行) 啟用慢查詢日誌後,預設把日誌檔案放在my.ini檔案中記錄的位置 在檔案中搜索:“datadir=”; 不要輕易更改此目錄,會造成索引失效。 3.set long_query_time=1;將慢查詢定義時間設定為1秒 4.show status like ‘slow_queries’;查詢有多少慢查詢 5.查日誌就可以把慢查詢揪出來了 二、索引:

索引為毛這麼快: 1.沒有索引時,需要全表檢索,即使很早檢索到資料也必須搜完所有表; 2.加完索引後,會建立一個索引檔案,這個索引檔案會將索引欄位的磁碟地址構建成一個二叉樹的資料結構進行儲存,搜尋時會進行二分查詢,一旦查詢到要查的資料就不需要找更下級的資料了,這樣就大大加大了查詢速度。 經過計算:檢索10次可以檢索1024條資料,檢索30次可以檢索10億的資料 主鍵索引: 建立: 1.當一張表,把某個列設定為主鍵時,則該列就是主鍵索引 2.alter table 表名 add primary key (列名); 查詢: 1.desc 表名; 該方法缺點是:不能夠顯示索引名 2.show index(es) from 表名; 3.show keys from 表名; 唯一索引:
1.當表的某列被指定為unique約束時,這列就是一個唯一索引 create table ddd(id int primary key auto_increment , name varchar(32) unique); 這時, name 列就是一個唯一索引. unique欄位可以為NULL,並可以有多NULL, 但是如果是具體內容,則不能重複. 主鍵欄位,不能為NULL,也不能重複. 2.在建立表後,再去建立唯一索引 create table eee(id int primary key auto_increment, name varchar(32)); create unique index 索引名 on 表名 (列表…); 全文索引: 應用場景:針對文字(檔案)的檢索,全文索引僅針對MyISAM有用 建立:

CREATE TABLE articles (
       id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
       title VARCHAR(200),
       body TEXT,
       FULLTEXT (title,body)
     )engine=myisam charset utf8;

使用: 1.在mysql中fulltext 索引只針對 myisam生效 2.mysql自己提供的fulltext針對英文生效->sphinx (coreseek) 技術處理中文 3.使用方法是 match(欄位名…) against(‘關鍵字’) 4.全文索引一個 叫 停止詞, 因為在一個文字中,如果使用常用詞建立索引是一個無窮大的數,因此,對一些常用詞和字元,就不會建立,這些詞,稱為停止詞. 普通索引: 建立: 先建立表再建立普通索引

create index  索引名 on 表名 (列);

索引刪除及修改: 刪除 alter table 表名 drop index 索引名; 如果刪除主鍵索引。 alter table 表名 drop primary key [這裡有一個小問題] 修改 先刪除,再重新建立. 索引的使用方法: 在如下情況新增索引比較合適: a: 經常作為where條件被使用 b: 該欄位的內容不是唯一的幾個值(sex) c: 欄位內容不是頻繁變化 會導致索引失效的語句: 1、使用like關鍵字模糊查詢時,% 放在前面索引不起作用,只有“%”不在第一個位置,索引才會生效(like ‘%文’–索引不起作用) 2、使用聯合索引時,只有查詢條件中使用了這些欄位中的第一個欄位,索引才會生效 3、使用OR關鍵字的查詢,查詢語句的查詢條件中只有OR關鍵字,且OR前後的兩個條件中的列都是索引時,索引才會生效,否則索引不生效。 4、儘量避免在where子句中使用!=或<>操作符,否則引擎將放棄使用索引而進行全表掃描。 5、對查詢進行優化,應儘量避免全表掃描,首先應考慮在where以及order by涉及的列上建立索引。 6、應儘量避免在 where 子句中對欄位進行表示式操作,這將導致引擎放棄使用索引而進行全表掃描。如:   select id from t where num/2=100   應改為:   select id from t where num=100*2 7、儘量避免在where子句中對欄位進行函式操作,將導致引擎放棄使用索引而進行全表掃描。 8、不要在 where 子句中的“=”左邊進行函式、算術運算或其他表示式運算,否則系統將可能無法正確使用索引。 9、並不是所有的索引對查詢都有效,sql是根據表中的資料來進行查詢優化的,當索引列有大量資料重複時,sql查詢不會去利用索引,如一表中有欄位   sex,male,female幾乎個一半,那麼即使在sex上建立了索引也對查詢效率起不了作用。 10、索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,   因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,   若太多則應考慮一些不常使用到的列上建的索引是否有 必要。 11、儘量使用數字型欄位,若只含數值資訊的欄位儘量不要設計為字元型,這會降低查詢和連線的效能,並會增加儲存開銷。   這是因為引擎在處理查詢和連線時會 逐個比較字串中每一個字元,而對於數字型而言只需要比較一次就夠了。 12、mysql查詢只使用一個索引,因此如果where子句中已經使用了索引的話,那麼order by中的列是不會使用索引的。    因此資料庫預設排序可以符合要求的情況下不要使用排序操作,儘量不要包含多個列的排序,如果需要最好給這些列建複合索引。 13、order by 索引 ,不起作用的問題(除了主鍵索引之外):   1、 如果select 只查詢索引欄位,order by 索引欄位會用到索引,要不然就是全表排列;

2、如果有where 條件,比如where vtype=1 order by vtype asc . 這樣order by 也會用到索引! 四種索引的使用場景: PRIMARY, INDEX, UNIQUE 這3種是一類 PRIMARY 主鍵。 就是 唯一 且 不能為空。 INDEX 索引,普通的 UNIQUE 唯一索引。 不允許有重複。 FULLTEXT 是全文索引,用於在一篇文章中,檢索文字資訊的。 舉個例子來說,比如你在為某商場做一個會員卡的系統。 這個系統有一個會員表 有下列欄位:

會員編號   INT
會員姓名   VARCHAR(10)
會員身份證號碼   VARCHAR(18)
會員電話   VARCHAR(10)
會員住址   VARCHAR(50)
會員備註資訊  TEXT

那麼這個 會員編號,作為主鍵,使用 PRIMARY 會員姓名 如果要建索引的話,那麼就是普通的 INDEX 會員身份證號碼 如果要建索引的話,那麼可以選擇 UNIQUE (唯一的,不允許重複) 會員備註資訊 , 如果需要建索引的話,可以選擇 FULLTEXT,全文搜尋。 不過 FULLTEXT 用於搜尋很長一篇文章的時候,效果最好。 用在比較短的文字,如果就一兩行字的,普通的 INDEX 也可以。 三、搜尋引擎的選擇: 1、MYISAM:預設的MySQL儲存引擎。如果應用是以讀操作和插入操作為主,只有很少的更新和刪除操作,並且對事務的完整性要求不是很高。其優勢是訪問的速度快。重要性不高的資料,如論壇的發帖、回帖。 2、Innodb:提供了具有提交、回滾和崩潰恢復能力的事務安全。但是對比MyISAM,寫的處理效率差一些並且會佔用更多的磁碟空間。重要性較高的資料,如訂單表、工資表。 3.Memory:儲存在記憶體當中,速度快,但會佔用和數量成正比的記憶體空間且資料在mysql重啟時會丟失。經常變化、查詢頻繁的臨時資料。 四、explain分析SQL: Explain select * from emp where ename=“zrlcHd”會產生如下資訊: select_type:表示查詢的型別。 table:輸出結果集的表 type:表示表的連線型別 possible_keys:表示查詢時,可能使用的索引 key:表示實際使用的索引key_len:索引欄位的長度rows:掃描出的行數(估算的行數) Extra:執行情況的描述和說明 五、常用SQL優化: 1.優化group by 語句 預設情況,MySQL對所有的group by col1,col2進行排序。這與在查詢中指定order by col1, col2類似。如果查詢中包括group by但使用者想要避免排序結果的消耗,則可以使用order by null禁止排序 2.有些情況下,可以使用連線來替代子查詢。因為使用join,MySQL不需要在記憶體中建立臨時表。 3.如果想要在含有or的查詢語句中利用索引,則or之間的每個條件列都必須用到索引,如果沒有索引,則應該考慮增加索引 select * from 表名 where 條件1=‘’ or 條件2=‘tt’