优化查询、访问量大时的优化
1.優(yōu)化查詢的方法
1.1使用索引
應(yīng)盡量避免全表掃描,首先應(yīng)考慮在 where 及 order by 、group by 涉及的列上建立索引。
1.1.1 為出現(xiàn)在where字句的字段建立一個索引
SELECT category_name FROM mytable WHERE category_id=1;為category_id建立一個索引:
CREATE INDEX mytable_categoryid ON mytable(category_id);若語句為:
SELECT category_name FROM mytable WHERE category_id=1 AND user_id=2;若再給user_id建立一個索引,這不是最佳方法??山⒍嘀厮饕?#xff1a;
CREATE INDEX mytable_categoryid_userid ON mytable(category_id,user_id);命名方式:表名—字段1名—字段2名
1.1.2 為order by子句中的字段建立一個索引
SELECT category_name FROM mytable WHERE category_id=1 AND user_id=2 ORDER BY adddate DESC;創(chuàng)建索引:
CREATE INDEX mytable_categoryid_useris_adddate ON mytable(category_id,user_id,adddate);注意:mytable_categoryid_uerid_adddate將會被截斷為:mytable_categoryid_uerid_addda
1.1.3 索引機制
本質(zhì):通過不斷地縮小想要獲取數(shù)據(jù)的范圍來篩選出最終想要的結(jié)果,同時把隨機的事件變成順序的事件,也就是說,有了這種索引機制,我們可以總是用同一種查找方式來鎖定數(shù)據(jù)。
1.2優(yōu)化SQL語句
1.2.1 通過explain來查看SQL語句執(zhí)行效果
將explain移到前面,查看執(zhí)行計劃;
可幫助選擇更好的索引和優(yōu)化查詢語句,寫出更好的優(yōu)化語句。
通常我們可以對比較復(fù)雜的尤其是涉及到多表的 SELECT 語句, 把關(guān)鍵字 EXPLAIN 加到前面, 查看執(zhí)行計劃。
- 例如: explain select name from news;
1.2.2?任何地方都不要使用 select * from t
用具體的字段列表代替“*” , 不要返回用不到的任何字段.
1.2.3 不在索引列做運算或者使用函數(shù)。
1.2.4?使用 limit
查詢盡可能使用 limit 減少返回的行數(shù), 減少數(shù)據(jù)傳輸時間和帶寬浪費。
1.3 優(yōu)化數(shù)據(jù)庫對象
1.3.1?優(yōu)化表的數(shù)據(jù)類型
使用 procedure analyse()函數(shù)對表進行分析, 該函數(shù)可以對表中列的數(shù)據(jù)類型提出優(yōu)化建議。
能小就用小。
表數(shù)據(jù)類型第一個原則是: 使用能正確的表示和存儲數(shù)據(jù)的最短類型。 這樣可以減少對磁盤空間、 內(nèi)存、 cpu 緩存的使用。
使用方法: select * from 表名 procedure analyse();
1.3.2?對表進行拆分
通過拆分表可以提高表的訪問效率。
有 2 種拆分方法:
1.3.3?使用中間表來提高查詢速度
創(chuàng)建中間表, 表結(jié)構(gòu)和源表結(jié)構(gòu)完全相同, 轉(zhuǎn)移要統(tǒng)計的數(shù)據(jù)到中間表, 然后在中間表上進行統(tǒng)計, 得出想要的結(jié)果。
1.4 硬件優(yōu)化
1.4.1 CPU 的優(yōu)化
選擇多核和主頻高的 CPU。
1.4.2 內(nèi)存的優(yōu)化使用更大的內(nèi)存。
將盡量多的內(nèi)存分配給 MYSQL 做緩存。
1.4.3 磁盤 I/O 的優(yōu)化
1.使用磁盤陣列
RAID 0 沒有數(shù)據(jù)冗余, 沒有數(shù)據(jù)校驗的磁盤陳列。 實現(xiàn) RAID 0至少需要兩塊以上的硬盤, 它將兩塊以上的硬盤合并成一塊, 數(shù)據(jù)
連續(xù)地分割在每塊盤上。
RAID1 是將一個兩塊硬盤所構(gòu)成 RAID 磁盤陣列, 其容量僅等于一塊硬盤的容量, 因為另一塊只是當作數(shù)據(jù)“鏡像”。
使用 RAID-0+1 磁盤陣列。 RAID 0+1 是 RAID 0 和 RAID 1 的組合形式。 它在提供與 RAID 1 一樣的數(shù)據(jù)安全保障的同時, 也提供了與 RAID 0 近似的存儲性能。
2.調(diào)整磁盤調(diào)度算法
選擇合適的磁盤調(diào)度算法, 可以減少磁盤的尋道時間。
1.5 MySQL 自身的優(yōu)化
對 MySQL 自身的優(yōu)化主要是對其配置文件 my.cnf 中的各項參數(shù)進行優(yōu)化調(diào)整。
- 如指定 MySQL 查詢緩沖區(qū)的大小,
- 指定 MySQL 允許的最大連接進程數(shù)等。
1.6?應(yīng)用優(yōu)化
1.6.1 使用數(shù)據(jù)庫連接池
1.6.2 使用查詢緩存
它的作用是存儲 select 查詢的文本及其相應(yīng)結(jié)果。
如果隨后收到一個相同的查詢, 服務(wù)器會從查詢緩存中直接得到查詢結(jié)果。
查詢緩存適用的對象是更新不頻繁的表, 當表中數(shù)據(jù)更改后, 查詢緩存中的相關(guān)條目就會被清空。
2.如果有一個特別大的訪問量到數(shù)據(jù)庫上, 怎么做優(yōu)化?
2.1.使用優(yōu)化查詢的方法(見上面)
2.2.主從復(fù)制, 讀寫分離, 負載均衡
目前,大部分的主流關(guān)系型數(shù)據(jù)庫都提供了主從復(fù)制的功能,通過配置兩臺(或多臺)數(shù)據(jù)庫的主從關(guān)系,可以將一臺數(shù)據(jù)庫服務(wù)器的數(shù)據(jù)更新同步到另一臺服務(wù)器上。
網(wǎng)站可以利用數(shù)據(jù)庫的這一功能,實現(xiàn)數(shù)據(jù)庫的讀寫分離,從而改善數(shù)據(jù)庫的負載壓力。
一個系統(tǒng)的讀操作遠遠多于寫操作,因此寫操作發(fā)向 master,讀操作發(fā)向 slaves 進行操作(簡單的輪循算法來決定使用哪個 slave)。
利用數(shù)據(jù)庫的讀寫分離,Web 服務(wù)器在寫數(shù)據(jù)的時候,訪問主數(shù)據(jù)庫(Master),主數(shù)據(jù)庫通過主從復(fù)制機制將數(shù)據(jù)更新同步到從數(shù)據(jù)庫(Slave),這樣當 Web 服務(wù)器讀數(shù)據(jù)的時候,就可以通過從數(shù)據(jù)庫獲得數(shù)據(jù)。這一方案使得在大量讀操作的 Web 應(yīng)用可以輕松地讀取數(shù)據(jù),而主數(shù)據(jù)庫也只會承受少量的寫入操作,還可以實現(xiàn)數(shù)據(jù)熱備份,可謂是一舉兩得的方案。
2.2.1 主從復(fù)制的原理:
影響 MySQL-A 數(shù)據(jù)庫的操作,在數(shù)據(jù)庫執(zhí)行后,都會寫入本地的日志系統(tǒng) A 中。
假設(shè),實時的將變化了的日志系統(tǒng)中的數(shù)據(jù)庫事件操作,通過網(wǎng)絡(luò)發(fā)給 MYSQL-B。
MYSQL-B 收到后,寫入本地日志系統(tǒng) B,然后一條條的將數(shù)據(jù)庫事件在數(shù)據(jù)庫中完成。
那么,MYSQL-A 的變化,MYSQL-B 也會變化,
這樣就是所謂的 MYSQL 的復(fù)制。
在上面的模型中,MYSQL-A 就是主服務(wù)器,即 master,MYSQL-B 就是從服務(wù)器,即slave。
日志系統(tǒng) A,其實它是 MYSQL 的日志類型中的二進制日志,也就是專門用來保存修改數(shù)據(jù)庫表的所有動作,即 bin log。
【注意 MYSQL 會在執(zhí)行語句之后,釋放鎖之前,寫入二進制日志,確保事務(wù)安全】
日志系統(tǒng) B,并不是二進制日志,由于它是從 MYSQL-A 的二進制日志復(fù)制過來的,并不是自己的數(shù)據(jù)庫變化產(chǎn)生的,有點接力的感覺,稱為中繼日志,即 relay log。
可以發(fā)現(xiàn),通過上面的機制,可以保證 MYSQL-A 和 MYSQL-B 的數(shù)據(jù)庫數(shù)據(jù)一致,但是時間上肯定有延遲,即 MYSQL-B 的數(shù)據(jù)是滯后的。
2.2.2 簡化版
mysql 主(稱 master)從(稱 slave)復(fù)制的原理:
2.2.3 簡要原理圖:
2.2.4 主從復(fù)制的方式
1.同步復(fù)制
主服務(wù)器在將更新的數(shù)據(jù)寫入它的二進制日志(Binlog)文件中后,必須等待驗證所有的從服務(wù)器的更新數(shù)據(jù)是否已經(jīng)復(fù)制到其中,之后才可以自由處理其它進入的事務(wù)處理請求。
2.異步復(fù)制
主服務(wù)器在將更新的數(shù)據(jù)寫入它的二進制日志(Binlog)文件中后,無需等待驗證更新數(shù)據(jù)是否已經(jīng)復(fù)制到從服務(wù)器中,就可以自由處理其它進入的事務(wù)處理請求。
3.半同步復(fù)制
主服務(wù)器在將更新的數(shù)據(jù)寫入它的二進制日志(Binlog)文件中后,只需等待驗證其中一臺從服務(wù)器的更新數(shù)據(jù)是否已經(jīng)復(fù)制到其中,就可以自由處理其它進入的事務(wù)處理請求,其他的從服務(wù)器不用管。
2.3 數(shù)據(jù)庫分表, 分區(qū), 分庫
2.3.1 分表
見上面描述。
2.3.2 分區(qū)
把一張表的數(shù)據(jù)分成多個區(qū)塊,這些區(qū)塊可以在一個磁盤上,也可以在不同的磁盤上。
分區(qū)后,表面上還是一張表,但數(shù)據(jù)散列在多個位置,這樣一來,多塊硬盤同時處理不同的請求,從而提高磁盤 I/O 讀寫性能,實現(xiàn)比較簡單。
包括水平分區(qū)和垂直分區(qū)。
2.3.3 分庫
根據(jù)業(yè)務(wù)不同把相關(guān)的表切分到不同的數(shù)據(jù)庫中,比如 web、bbs、blog 等庫。
?
?
?
總結(jié)
以上是生活随笔為你收集整理的优化查询、访问量大时的优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。