mysql優化sql語句的方法

1.對查詢進行優化,應儘可能避免全表掃描,首先應考慮在 where 及 order by 涉及的列上創建索引。 mysql


2.應儘可能避免在 where 子句中使用!=或<>操做符,不然將引擎放棄使用索引而進行全表掃描。 

3.應儘可能避免在 where 子句中對字段進行 null 值判斷,不然將致使引擎放棄使用索引而進行全表掃描,如:
select id from t where num is null 
能夠在num上設置默認值0,確保表中num列沒有null值,而後這樣查詢: 
select id from t where num=0 

4.應儘可能避免在 where 子句中使用 or 來鏈接條件,不然將致使引擎放棄使用索引而進行全表掃描,如: 
select id from t where num=10 or num=20 
能夠這樣查詢: 
select id from t where num=10 
union all 
select id from t where num=20 

5.下面的查詢也將致使全表掃描: 
select id from t where name like '%abc%' 
若要提升效率,能夠考慮全文檢索。 

6.in 和 not in 也要慎用,不然會致使全表掃描,如: 
select id from t where num in(1,2,3) 
對於連續的數值,能用 between 就不要用 in 了: 
select id from t where num between 1 and 3 

7.若是在 where 子句中使用參數,也會致使全表掃描。由於SQL只有在運行時纔會解析局部變量,但優化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然而,若是在編譯時創建訪問計劃,變量的值仍是未知的,於是沒法做爲索引選擇的輸入項。以下面語句將進行全表掃描: 
select id from t where num=@num 
能夠改成強制查詢使用索引: 
select id from t with(index(索引名)) where num=@num 

8.應儘可能避免在 where 子句中對字段進行表達式操做,這將致使引擎放棄使用索引而進行全表掃描。如: 
select id from t where num/2=100 
應改成
select id from t where num=100*2 

9.應儘可能避免在where子句中對字段進行函數操做,這將致使引擎放棄使用索引而進行全表掃描。如: 
select id from t where substring(name,1,3)='abc'--name以abc開頭的id 
select id from t where datediff(day,createdate,'2005-11-30')=0--'2005-11-30'生成的id 
應改成
select id from t where name like 'abc%' 
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1' 

10.不要在 where 子句中的「=」左邊進行函數、算術運算或其餘表達式運算,不然系統將可能沒法正確使用索引。 

11.在使用索引字段做爲條件時,若是該索引是複合索引,那麼必須使用到該索引中的第一個字段做爲條件時才能保證系統使用該索引,不然該索引將不會被使用,而且應儘量的讓字段順序與索引順序相一致。 

12.不要寫一些沒有意義的查詢,如須要生成一個空表結構: 
select col1,col2 into #t from t where 1=0 
這類代碼不會返回任何結果集,可是會消耗系統資源的,應改爲這樣: 
create table #t(...) 

13.不少時候用 exists 代替 in 是一個好的選擇: 
select num from a where num in(select num from b) 
用下面的語句替換: 
select num from a where exists(select 1 from b where num=a.num) 

14.並非全部索引對查詢都有效,SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重複時,SQL查詢可能不會去利用索引,如一表中有字段sex,male、female幾乎各一半,那麼即便在sex上建了索引也對查詢效率起不了做用。 

15.索引並非越多越好,索引當然能夠提升相應的 select 的效率,但同時也下降了 insert 及 update 的效率,由於 insert 或 update 時有可能會重建索引,因此怎樣建索引須要慎重考慮,視具體狀況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。 

16.應儘量的避免更新 clustered 索引數據列,由於 clustered 索引數據列的順序就是表記錄的物理存儲順序,一旦該列值改變將致使整個表記錄的順序的調整,會耗費至關大的資源。若應用系統須要頻繁更新 clustered 索引數據列,那麼須要考慮是否應將該索引建爲 clustered 索引。 

17.儘可能使用數字型字段,若只含數值信息的字段儘可能不要設計爲字符型,這會下降查詢和鏈接的性能,並會增長存儲開銷。這是由於引擎在處理查詢和鏈接時會逐個比較字符串中每個字符,而對於數字型而言只須要比較一次就夠了。 

18.儘量的使用 varchar/nvarchar 代替 char/nchar ,由於首先變長字段存儲空間小,能夠節省存儲空間,其次對於查詢來講,在一個相對較小的字段內搜索效率顯然要高些。 

19.任何地方都不要使用 select * from t ,用具體的字段列表代替「*」,不要返回用不到的任何字段。 

20.儘可能使用表變量來代替臨時表。若是表變量包含大量數據,請注意索引很是有限(只有主鍵索引)。 

21.避免頻繁建立和刪除臨時表,以減小系統表資源的消耗。 

22.臨時表並非不可以使用,適當地使用它們可使某些例程更有效,例如,當須要重複引用大型表或經常使用表中的某個數據集時。可是,對於一次性事件,最好使用導出表。 

23.在新建臨時表時,若是一次性插入數據量很大,那麼可使用 select into 代替 create table,避免形成大量 log ,以提升速度;若是數據量不大,爲了緩和系統表的資源,應先create table,而後insert。 

24.若是使用到了臨時表,在存儲過程的最後務必將全部的臨時表顯式刪除,先 truncate table ,而後 drop table ,這樣能夠避免系統表的較長時間鎖定。 

25.儘可能避免使用遊標,由於遊標的效率較差,若是遊標操做的數據超過1萬行,那麼就應該考慮改寫。 

26.使用基於遊標的方法或臨時表方法以前,應先尋找基於集的解決方案來解決問題,基於集的方法一般更有效。 

27.與臨時表同樣,遊標並非不可以使用。對小型數據集使用 FAST_FORWARD 遊標一般要優於其餘逐行處理方法,尤爲是在必須引用幾個表才能得到所需的數據時。在結果集中包括「合計」的例程一般要比使用遊標執行的速度快。若是開發時間容許,基於遊標的方法和基於集的方法均可以嘗試一下,看哪種方法的效果更好。 

28.在全部的存儲過程和觸發器的開始處設置 SET NOCOUNT ON ,在結束時設置 SET NOCOUNT OFF 。無需在執行存儲過程和觸發器的每一個語句後向客戶端發送 DONE_IN_PROC 消息。 

29.儘可能避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。 

30.儘可能避免大事務操做,提升系統併發能力。sql

一、爲何要進行mysql優化?數據庫

假設咱們設置一個數據量超過10萬條記錄的表,來進行咱們常常作的查詢操做好比:select * from 表名,服務器很慢甚至卡死,須要咱們重啓數據庫服務器,這說明咱們的表或者查詢SQL是有問題的,因此咱們要進行mysql優化服務器

二、數據庫優化的目標?mysql優化

經過各類對數據庫的優化方法,獲取最高的查詢和加載性能,達到查詢性能的提升和加載性能的提升。併發

三、掌握優化的方式和途徑數據庫設計

建表、索引、配置、SQL語句都須要優化分佈式

四、掌握建表和分表優化?函數

①數據庫表設計符合範式要求:性能

第一範式(1NF):是指數據庫表的每一列都是不可分割的基本數據項

第二範式(2NF)要求數據庫表中的每一個實例或行必須能夠被惟一的區分

第三範式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。

適當反三範式。。。。

②數據庫字段的設置要合理

介紹經常使用數據類型的特色及如何選擇合適的數據類型:

int 4個字節

char 

varchar 

text 存儲文件

decimal 存金錢

enum(枚舉)只適合存字符串

float4個字節

③爲何要分表?

數據庫中的數據量不必定是可控的,在未進行分表的狀況下,隨着時間和業務的發展,庫中的表會愈來愈多,表中的數據量也會愈來愈大,相應地,數據操做,增刪改查的開銷也會愈來愈大;另外,因爲沒法進行分佈式式部署,而一臺服務器的資源(CPU、磁盤、內存、IO等)是有限的,最終數據庫所能承載的數據量、數據處理能力都將遭遇瓶頸。

④什麼是分表?

本來存儲於一個表的數據分塊存儲到多個表上

五、掌握數據庫的查詢優化

①關鍵字通常放在SELECT查詢語句的前面,用於描述MySQL如何執行查詢操做、以及MySQL成功返回結果集須要執行的行數。

解釋輸出列的含義(備註):

select title from article where title like '菲律賓%';

②數據庫的優化查詢主要有如下幾個規則:

避免全表掃描 eg:select * from 表名;(不可取)

儘可能使用索引查詢 eg:select age from user where age>10;

避免使用select *

儘可能使用數字型字段(把包含數值信息的字段設計爲字符型,會下降查詢和連接的性能,引擎在處理查詢和連接會逐個比較字符串中的每一個字符 ,而對於數字型而言只須要比較一次就夠了)

避免向客戶返回大量數據

避免大的事務性操做,提升系統併發能力

一個插入500萬行的事務,有索引2個

致使別的操做緩慢,若是改爲每次 插入5萬行,插100次,這樣別的操做會受影響小嗎?

五、掌握MySQL數據庫的索引優化

六、掌握數據庫的配置優化

七、掌握數據庫的查詢優化

通常來講,要保證數據庫的效率,要作好如下四個方面的工做:數據庫設計、sql語句優化、數據庫參數配置、恰當的硬件資源和操做系統,這個順序也表現了這四個工做對性能影響的大小。

數據庫設計

一、適度的反範式,注意是適度的:三範式最大的問題在於查詢時一般須要join不少表,致使查詢效率很低。因此有時候基於性能考慮,咱們須要有意的違反三範式,適度的作冗餘, 以達到提升查詢效率的目的

二、適當創建索引:建索引查詢速度的提升是以插入、更新、刪除的速度爲代價的,建索引還佔內存。

    建索引規則: 1. 索引的字段必須是常常做爲查詢條件的字段;  2. 若是索引多個字段,第一個字段要是常常做爲查詢條件的。若是隻有第二個字段做爲查詢條件,這個索引不會起到做用;  3. 索引的字段必須有足夠的區分度;  4. Mysql 對於長字段支持前綴索引;

三、對錶進行水平劃分:若是一個表的記錄數太多了,好比上千萬條,並且 須要常常檢索,那麼咱們就有必要化整爲零了。。固然這須要數據在邏輯上能夠劃分。一個好的劃分依據,有 利於程序的簡單實現,也能夠充分利用水平分表的優點。

四、對錶進行垂直劃分

相關文章
相關標籤/搜索