分享關於資料庫優化經驗

2021-09-19 10:35:38 字數 3364 閱讀 2623

我們在開發過程中,多多少少都會接觸稍微複雜一點的業務,那麼往往也關係到多表的查詢,而就在此時我們也頭疼多表查詢帶來的效能問題,在此我分享我這些年自己的優化經驗。

1、在sql語句中我們很多時候會使用子查詢,如:

select a.col1,a.col2,a.col3,a.col4,(select b.col2 from table2 b where a.col1=b.col1) bcol from table a order by a.create_time;

問題:這條語句我們能完成自身的業務,但當資料量大的時候就會出現效能查的問題,因為在使用子查詢的時候資料庫需要建立臨時表,而後執行完成還要執行銷毀操作,對此對於資料庫增加了很大的負擔。

解決:對於多表查詢,我們可以採用關聯查詢,效能相對提公升了,但還是有很大問題,如:

select a.col1,a.col2,a.col3,a.col4,b.col2 bcol from table a,table b where a.col1=b.col1 order by a.create_time;

在a、b、c三張表中a錶主業務大表,其中有百萬級資料,而b、c表為小表各存有幾千或者幾萬條資料,當我們通過關聯查詢時間為10秒,20秒,我相信大家都無法接受的,那麼我們是否可以通過業務展示層考慮將b、c表的部分業務資料冗餘在a表中的,比如查詢的列表資料為a表的資料有10個字段,b、c表中的資料各2個,那麼我們可以講b、c表中需要在查詢列表展示的資料冗餘在a表中,那麼這就變成了單錶查詢,效能又再一次的提公升。當然它的瓶頸就在與對修改操作時你需要維護多張表。

3、很多朋友都會說,我在sql優化時首先想到了為表建立索引,那麼你是否去真實測試過你的sql語句命中了索引了嗎?又是否命中了多個索引呢?

這時候mysql資料庫就為我們提供了執行計畫這個工具:explain

語法:explain + sql

我們就關注(此處內容出處 

possible_keys:顯示可能應用在這張表中的索引。如果為空,沒有可能的索引。

key: 實際使用的索引。如果為null,則沒有使用索引。

key_len:使用的索引的長度。

rows:mysql認為必須檢查的用來返回請求資料的行數。

如何判斷乙個sql語句充分用到了索引呢?那就是key_len的長度了,下面說明下怎麼去計算:

latin1乙個字元占用1個位元組,gbk乙個字元占用2個位元組,utf8乙個字元占用3個位元組

char,int,datetime,需要有是否為空的標記,這個標記占用1個位元組(對於not null的字段來說,則不需要這1位元組);

varchar,除了是否為空的標記外,還需要有長度資訊,需要占用2個位元組。

綜上,下面來看一些例子:

列型別key_len

備註id int

key_len = 4+1

int為4bytes,允許為null,加1byte

id bigint not null

key_len=8

bigint為8bytes

user char(30) utf8

key_len=30*3+1

utf8每個字元為3bytes,允許為null,加1byte

user varchar(30) not null utf8

key_len=30*3+2

utf8每個字元為3bytes,變長資料型別,加2bytes

user varchar(30) utf8

key_len=30*3+2+1

utf8每個字元為3bytes,允許為null,加1byte,變長資料型別,加2bytes

detail text(10) utf8

key_len=30*3+2+1

text擷取部分,被視為動態列型別。

備註:key_len只指示了where中用於條件過濾時被選中的索引列,是不包含order by/group by這一部分被選中的索引列的。

如果你的索引是復合索引,那麼多個索引的總長度為key_len時,你的索引就充分利用到了。

附網上的索引使用口訣:

全職匹配我最愛,最左字首要遵守;

帶頭大哥不能死,中間兄弟不能斷;

索引列上少計算,範圍之後全失效(範圍查詢放最後);

like百分寫最右,覆蓋索引不寫星;

不等空值還有or,索引失效要少用;

var引號不可丟,sql高階也不難。

4、最左字首原則:

我們建立乙個復合索引由col1、col2、col3組成。

select * from table where col1 = 'a';  --命中1個索引(col1)

select * from table where col2 = 'b';  --沒有命中索引

select * from table where col2 = 'b' and col3 = 'c';   --沒命中索引

select * from table where col1 = 'a' and col3 = 'c';  --只命中了1個索引(col1 )

從而可以得出上面的口訣:帶頭大哥不能死,中間兄弟不能斷。

5、我們往往乙個業務需要查詢多種資料,如果說資料格式很相似,在此我向各位推薦使用union all,通過一條語句查詢出我們所需要的所有資料,減少與資料庫連線次數,從而提公升效能。另在where條件中的in和or我們也可以考慮使用。

6、mysql中還存在預熱的功能,大部分專案都會有熱點資料的存在,也就是常常被查詢的資料,資料庫會將其放置到記憶體中為提高效能做的優化,而資料庫在重啟時熱點資料會被清空,那麼這時候就要我們手動的去預熱來盡快的滿足我們的需要:

獲得資料庫裡面的庫和對應的表,來進行預熱(5.0以上版本):select table_schema, table_name from db.tables

7、資料庫避免使用null,可以使用乙個預設值去替換,同時在查詢的時候不要在where條件語句中寫任何計算的語句,盡可能將所有的資料都通過應用程式去獲取計算好再傳入到sql語句引數中執行。

8、對查詢進行優化,要盡量避免全表掃瞄,首先應考慮在 where 及 order by 涉及的列上建立索引。

where 子句中使用 != 、 <> 、or、in、not in、like很大可能會放棄索引,檢索全表資料,效能極差。

充分考慮 union all、exists的使用。

查詢語句中將明確需要的資料字段一一寫明,不要使用 select * 去查詢資料。

可能並不完善或者說並不正確,還請路過的大神指點一二,大家共同**進步。

關於資料庫優化

最近公司對專案進行sql語句優化,正好我總結一下,可能不全 1.in 和 exist 中選則使用exist 2.from後面接的表名稱,在oracle中由於是從右往左執行的,所以表中資料比較少的寫在最右邊 3.where中存在表連線的,放到最前面 4.where查詢條件能過濾最多的資料放到最後 5....

關於資料庫優化

資料庫優化的幾個方面 sql語句以及有效索引 資料結構 系統配置 硬體 1.sql以及索引的優化是最重要的。首先要根據需求寫出結構良好的sql,然後根據sql在表中建立有效的索引。但是如果索引太多,不但會影響寫入的效率,對查詢也有一定的影響。2.要根據一些正規化來進行表結構的設計。設計表結構時,就需...

資料庫開發的效能優化經驗

一 問題的提出 在應用系統開發初期,由於開發資料庫資料比較少,對於查詢sql語句,複雜檢視的的編寫等體會不出sql語句各種寫法的效能優劣,但是如果將應用系統提交實際應用後,隨著資料庫中資料的增加,系統的響應速度就成為目前系統需要解決的最主要的問題之一。系統優化中乙個很重要的方面就是sql語句的優化。...