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.查日誌就可以把慢查詢揪出來了 二、索引:
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’