關於資料庫優化

2021-09-19 14:30:43 字數 3131 閱讀 1815

資料庫優化的幾個方面:sql語句以及有效索引、資料結構、系統配置、硬體

1. sql以及索引的優化是最重要的。首先要根據需求寫出結構良好的sql,然後根據sql在表中建立有效的索引。但是如果索引太多,不但會影響寫入的效率,對查詢也有一定的影響。

2. 要根據一些正規化來進行表結構的設計。設計表結構時,就需要考慮如何設計才能夠更有效的查詢。

3. 系統配置的優化。mysql資料庫是基於檔案的,如果開啟的檔案數達到一定的數量,無法開啟之後就會進行頻繁的io操作。

4. 硬體優化。更快的io、更多的記憶體。一般來說記憶體越大,對於資料庫的操作越好。但是cpu多就不一定了,因為他並不會用到太多的cpu數量,有很多的查詢都是單cpu。另外使用高的io(ssd、raid),但是io並不能減少資料庫鎖的機制。所以說如果查詢緩慢是因為資料庫內部的一些鎖引起的,那麼硬體優化就沒有什麼意義。

、sql語句優化

1、通過慢查詢日誌發現有效率問題的sql

可以通過開啟慢查詢日誌的方式進行定位有問題的sql

(1)檢視mysql是否開啟慢查詢日誌

show variables like 'slow_query_log';

(2)設定沒有索引的記錄到慢查詢日誌

set global log_queries_not_using_indexes=on;

(3)檢視超過多長時間的sql進行記錄到慢查詢日誌

show variables like 'long_query_time'

(4)開啟慢查詢日誌

set global slow_query_log=on

(5)設定超時時間

set global long_query_time=5;--超過5s的語句才記錄日誌

(6)檢視慢查詢日誌的位置 show variables like 'slow%'

2、慢查詢日誌內容分析

慢查詢日誌主要分為5部分,第一部分是慢查詢時間,第二部分是慢查詢的**主機和使用者,第三部分是查詢的執行時間、鎖定時間、傳送的行數、掃瞄的行數。最後是時間戳形式記錄的命令以及該命令的執行的時間戳。

系統執行一段時間後,慢查詢日誌可能比較多,需要通過mysqldumpslow、pt-query-digest等工具分析慢查詢日誌。參考這裡

。3、通過explain檢視sql的執行計畫

具體的分析過程可以參考這裡

,裡面的例子描述的很清晰。

、索引優化

1、選擇索引

(1)選擇合適的索引列,選擇在where,group by,order by,on從句**現的列作為索引項,對於離散度不大的列沒有必要建立索引。

(2)索引字段越小越好(因為資料庫的儲存單位是頁,一頁中能存下的資料越多越好 )

(3)離散度大得列放在聯合索引前面

判斷離散程度的方法是:

select count(distinct ziduan1),count(distinct ziduan2) from tablename

越大越離散

2、索引優化方法

索引一般情況下都是高效的。不過凡是都有兩面性,索引是以空間換時間的一種策略,索引本身在提高查詢效率的同時會影響插入、更新、刪除的效率。不當的使用索引不僅增加了寫操作的負擔,也會影響讀取的效率。索引越多,資料庫分析的越慢。注意點:

(1)innodb 每個索引都會加上主鍵,聯合索引不要加上主鍵,innodb會自動加,否則會冗餘。

(2)索引存在的目的是為了加快查詢的效率,不過不是索引越多越好,建立索引要適當才好。過多的索引會增加資料庫判斷使用什麼索引來查詢的開銷,所以,有時候也會出現以去掉重複或者無效的索引為優化手段的優化方式。

(3)主鍵已經是索引了,所以primay key 的主鍵不用再設定unique唯一索引了。

3、索引的原理可以參考這裡

或者這裡

。理解索引原理對於索引優化有很大幫助。

、資料表結構優化

1、選擇合適的資料型別

(1)使用可存下資料的最小的資料型別。

(2)使用簡單地資料型別,int要比varchar型別在mysql處理上更簡單。

(3)盡可能使用not null定義字段,這是由innodb的特性決定的,因為非not null的資料可能需要一些額外的字段進行儲存,這樣就會增加一些io。可以對非null的字段設定乙個預設值。

(4)盡量少用text,非用不可最好分表,將text欄位存放到另一張表中,在需要的時候再使用聯合查詢,這樣可提高查詢主表的效率。

例子1、用int儲存日期時間

from_unixtime()可將int型別的時間戳轉換為時間格式

select from_unixtime(1392178320); 輸出為 2014-02-12 12:12:00unix_timestamp()可將時間格式轉換為int型別

select unix_timestamp('2014-02-12 12:12:00'); 輸出為1392178320

例子2、儲存ip位址——bigint

利用inet_aton(),inet_ntoa()轉換

select inet_aton('192.169.1.1'); 輸出為3232301313

select inet_ntoa(3232301313); 輸出為192.169.1.1

四、資料庫配置優化

這方面目前了解的並不多,參考這裡

吧。五、硬體優化

硬體層面的優化是最後的手段。主要需考慮cpu、儲存、網路等幾個方面。

cpu:cpu並不是越多越好,之前看到網上的分析有說很多的查詢都是單cpu的,增加cpu數量並不能提高效能。

儲存:機械磁碟 or ssd(當然是ssd更快);單個大磁碟 or 多個小磁碟組合使用(單個1t的磁碟應該沒有2個500g磁碟的組合快,因為磁碟的轉速都是固定的,兩個磁碟相當於可以並行的讀取)

網路:一般不是問題,但是在分布式的集群環境中,各個資料庫節點之間的網路環境經常會稱為系統的瓶頸。另外,如果服務端和資料庫分布在不同的城市,一條簡單sql傳輸的時間可能就要幾十毫秒。

關於資料庫優化

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

關於資料庫優化(開篇)

接觸sql蠻久了,自覺對裡面的優化是最感興趣的,接觸的專案都比較大,很多表都是幾千萬數量級的,同時又要求系統對這些錶能進行高效的讀寫,身邊的同事都比較怕這塊,一有鎖表或者其他優化上的問題大都束手無策,很多時候我只能自己動手解決問題了,也積累一些經驗。這裡寫的很多都是自己的觀點,甚至是猜測和實踐得出的...

分享關於資料庫優化經驗

我們在開發過程中,多多少少都會接觸稍微複雜一點的業務,那麼往往也關係到多表的查詢,而就在此時我們也頭疼多表查詢帶來的效能問題,在此我分享我這些年自己的優化經驗。1 在sql語句中我們很多時候會使用子查詢,如 select a.col1,a.col2,a.col3,a.col4,select b.co...