簡單一點,上來就說說資料庫優化。本文都是基於mysql資料庫的優化建議。分為四個方面:索引優化、sql優化、建表優化和引數優化。
索引優化
首先介紹下索引。索引是資料庫中乙個排序的資料結構,用於快速查詢和更新資料。根據結構形式可分為b樹索引(b-tree)、雜湊索引(hash)、空間索引(r-tree)和全文索引(full-text)。
mysql有兩大資料庫引擎,分別為myisam和innodb,其中innodb支援事務。下面說說innodb
的索引結構:索引鍵值的邏輯順序和索引鎖服務的表相應的物理順序相同(即聚集索引,cluster index),也就是說,資料和索引(b+樹)在一起,記錄被真實儲存在索引葉子中。如下圖所示:
需要注意的是,mysql索引僅支援最左字首原則(比如 like 'xx%'),同時不支援函式索引和使用in範圍查詢。
索引使用還有如下原則:
1.索引字段不要超過5個,單錶索引盡量不超過5個;
2.order by、group by和distinct欄位放在復合索引的後面,即復合索引前面字段用於等值查詢,後面字段用於判斷;
3.update語句根據where條件增加索引;
4.把範圍條件放在符合索引的最後,因為between、、>=會導致後面條件用不了索引;
5.資料區分度不大的字段不宜使用索引;
sql優化
order by、group by優化
1.盡量對較少的行排序;
2.如果連線多張表。order by的列應該屬於連線順序第一張表;
3.order by、group by的列盡量都在第一張表中;
4.保證索引列和order by列相同,且順序一致;
5.增加read_rnd_buffer_size(mysql的隨機讀緩衝區大小)
分頁語句優化
mysql的分頁語句為:
select * from table where col = *** limit m , n;
越往後翻頁速度越慢,因為mysql會讀取m+n條資料,m越大效能越差。可考慮改為如下方式:
select t1.* from table t1 ,
(select col from table where col = *** limit m , n) t2
where t1.col = t2.col ;
或當條件是主鍵id時:
select * from table where id>=2345 limit 11;
select * from table where id>=(select id from table limit 10000,1) limit 10;
select * from table inner join (select id from table limit 10000,10) using (id);
子查詢優化
當有如下sql:
select first_name from employee where emp_no in (
select emp_no from salary where salary = 5000);
這樣會遍歷employee表每條記錄帶入子查詢中,可改為:
select first_name from emplyee emp ,
(select emp_no from salary where salary = 5000) sal
where emp.emp_no = sal.emp_no;
其他一些sql建議
盡量不用select *
1.減少表變化時的影響;
2.可以使用到covering index;
3.select/join減少硬碟臨時表生成
or條件改為in
or時間複雜度:o(n);in時間複雜度:o(log n)。[n最好小於200條]
避免負向查詢
not、!和<>
1.不能使用索引
2.很可能全表掃瞄
數值比對
1.數字對數字,字元對字元;
2.數值和字元比較先轉換為雙精度進行比對;
3.字元和數字比較:字元轉數值,不會使用索引;
建表優化
建表前首先對資料量預估,一年內的單錶資料量純int不超1000w,含char不超500w。如果會超過,建議考慮分表,可基於userid、date或area合理實現。
建議單庫不超過300-400個表,表的字段少而精,好處io高效,遍歷快,修復快,提高併發,alter快。單表字段數控制在20-50個,不超50個純int,20個char(10)。
避免使用null欄位:1.很難查詢優化;2.null加索引,需要額外空間;3.含null復合索引無效。盡量不用text/blob資料型別:強制生成硬碟臨時表;浪費空間,可想辦法拆分欄位到單獨的表。
盡量不用外來鍵:1.額外開銷;2.逐行操作;3.高併發容易死鎖。
數字型的索引比字串型快:更高效,查詢更快,空間更小。
引數優化
innodb_buffer_pool_size
innodb引擎緩衝池大小,主要快取了索引和資料。如果sql查詢的資料在快取中已快取,則不需要從磁碟中讀取,建議設定為主機記憶體的70-80%。
innodb緩衝池
快取了行資料、索引、插入緩衝和鎖等。innodb還使用緩衝池幫助延遲寫入,這樣就可以合併多個寫入操作一起順序寫回。
innodb_log_file_size
日誌組裡日誌檔案大小。建議256m或更大,預設5m。
innodb_flush_log_at_trx_commit
預設1。設為2時,每個事務提交時日誌緩衝被寫到檔案上,但不對日誌檔案做刷盤操作。刷盤每秒發生一次。建議設2。
sysc_binlog
預設0。不實時將二進位制日誌中的語句刷盤。設定大於1時實時。建議設0。
tmp_table_size
決定內部記憶體臨時表最大值,每個執行緒都會分配,如果記憶體臨時表超過限制,mysql就會把它轉為基於磁碟的myisam表。group by和distinct等不能走索引的sql會總臨時表,適當加大tmp_table_size和max_heap_table_size的值。
table_open_cache
指定表快取記憶體大小。每當mysql訪問一張表,如果表緩衝區還有空間,該錶就被開啟放入其中,這樣可以加快訪問表內容。
query_cache_size
控制mysql query cache的大小。如果mysql開啟query cache,在執行每個query時會先鎖住query cache,然後判斷是否存在query cache,如果存在則返回;不存在則進行引擎查詢。同時insert、update和delete會將query cache失效掉,所以適合寫少讀多的情況。
MySQL優化 SQL優化
其實sql語句的優化核心就在避免全表掃瞄上面 對查詢語句優化,避免全表掃瞄 首先應考慮在where及order by涉及的列上建立索引 避免在where子句中對字段進行表示式和函式操作 避免where進行null 等運算導致的全表掃瞄 在group by後面增加order by null就可以防止g...
Mysql優化 SQL語句優化
索引優化 where 字段 組合索引 最左字首 索引下推 非選擇行 不加鎖 索引覆蓋 不回表 on兩邊 排序 分組 explain分析語句情況,看建立索引沒,或者建立錯誤,響應時間長的話可以看下慢查詢日誌 盡量不要用 查所有字段的話,select查詢列中的字段如果沒有索引的話,會造成回表 limit...
MySQL 常用SQL優化
mysql 常用sql優化 一.大批量插入資料 1.對於load myisam儲存引擎的表,可以通過關閉開啟myisam表非唯一索引的更新來提公升匯入速度 例 mysql alter table tbl name disable keys mysql load data infile home my...