MySQL數(shù)據(jù)庫(kù)優(yōu)化SQL語(yǔ)句的步驟4
以上的文章我們講過(guò)MySQL數(shù)據(jù)庫(kù)優(yōu)化SQL語(yǔ)句的前三步驟,今天我們就和大家一起來(lái)講述MySQL數(shù)據(jù)庫(kù)優(yōu)化SQL語(yǔ)句的實(shí)際操作的第四步驟,以下就是文章的具體內(nèi)容描述,望你在瀏覽之后會(huì)有所收獲。
1:索引的使用,索引的重要性就不說(shuō)了,功能也不說(shuō)了,只說(shuō)怎么做. 首先要明確所有的MySQL(和PHP搭配之最佳組合)索引(Prima(最完善的虛擬主機(jī)管理系統(tǒng))ry,unique,index)在b樹中有存儲(chǔ).索引主要用語(yǔ):
a:快速找到where指定條件的記錄 b:執(zhí)行聯(lián)結(jié)時(shí),從其他表檢索行 c:對(duì)特定的索引列找出max()和min()值
d:如果排序或者分組在一個(gè)可用鍵的最前面加前綴,排序或分組一個(gè)表
e:一個(gè)查詢可能被用來(lái)MySQL數(shù)據(jù)庫(kù)優(yōu)化檢索值,而不用訪問(wèn)數(shù)據(jù)文件.如果某些表的列是數(shù)字型并且正好是某個(gè)列的前綴,為了更快,值可以從索引樹中取出
2:存儲(chǔ)或者更新數(shù)據(jù)的查詢速度 grant的執(zhí)行會(huì)稍稍的減低效率.
MySQL(和PHP搭配之最佳組合)的函數(shù)應(yīng)該被高度的優(yōu)化.可以用benchmark(loop_count,expression)來(lái)找出是否查詢有問(wèn)題
select的查詢速度:如果想要讓一個(gè)select...where...更快,我能想到的只有建立索引.可以在一個(gè)表上運(yùn)行myisamchk--analyze來(lái)更好的MySQL數(shù)據(jù)庫(kù)優(yōu)化查詢.可以用myisamchk--sort-index--sort-records=1來(lái)設(shè)置用一個(gè)索引排序一個(gè)索引和數(shù)據(jù).
3:MySQL(和PHP搭配之最佳組合)優(yōu)化where子句
3.1:刪除不必要的括號(hào):
((a AND b) AND c OR (((a AND b) AND (a AND d))))>(a AND b AND c) OR (a AND b AND c AND d)
3.2:使用常數(shù)
(ab>5 AND b=c AND a=5
3.3:刪除常數(shù)條件
(b>=5 AND b=5) OR (b=6 AND 5=5) OR (b=100 AND 2=3) >b=5 OR b=6
3.4:索引使用的常數(shù)表達(dá)式僅計(jì)算一次
3.5:在一個(gè)表中,沒有一個(gè)where的count(*)直接從表中檢索信息
3.6:所有常數(shù)的表在查詢中在任何其他表之前讀出
3.7:對(duì)外聯(lián)結(jié)表最好聯(lián)結(jié)組合是嘗試了所有可能性找到的
3.8:如果有一個(gè)order by字句和一個(gè)不同的group by子句或者order by或者group by包含不是來(lái)自聯(lián)結(jié)的第一個(gè)表的列,那么創(chuàng)建一個(gè)臨時(shí)表
3.9:如果使用了sql_small_result,那么msyql使用在內(nèi)存中的一個(gè)表
3.10:每個(gè)表的索引給查詢并且使用跨越少于30%的行的索引.
3.11在每個(gè)記錄輸出前,跳過(guò)不匹配having子句的行
4:MySQL數(shù)據(jù)庫(kù)優(yōu)化left join
在MySQL(和PHP搭配之最佳組合)中 a left join b按以下方式實(shí)現(xiàn)
a:表b依賴于表a
b:表a依賴于所有用在left join條件的表(除了b)
c:所有l(wèi)eft join條件被移到where子句中
d:進(jìn)行所有的聯(lián)結(jié)MySQL數(shù)據(jù)庫(kù)優(yōu)化,除了一個(gè)表總是在所有他依賴的表后讀?。绻幸粋€(gè)循環(huán)依賴,那么將發(fā)生錯(cuò)誤
e:進(jìn)行所有的標(biāo)準(zhǔn)的where優(yōu)化 f:如果在a中有一行匹配where子句,但是在b中沒有任何匹配left join條件,那么,在b中生成的所有設(shè)置為NULL的一行
g:如果使用left join來(lái)找出某些表中不存在的行并且在where部分有column_name IS NULL測(cè)試(column_name為NOT NULL列).那么,MySQL(和PHP搭配之最佳組合)在它已經(jīng)找到了匹配left join條件的一行后,將停止在更多的行后尋找
5:MySQL數(shù)據(jù)庫(kù)優(yōu)化limit
a:如果用limit只選擇一行,當(dāng)MySQL(和PHP搭配之最佳組合)需要掃描整個(gè)表時(shí),它的作用相當(dāng)于索引
b:如果使用limit#與order by,MySQL(和PHP搭配之最佳組合)如果找到了第#行,將結(jié)束排序,而不會(huì)排序正個(gè)表
c:當(dāng)結(jié)合limit#和distinct時(shí),MySQL(和PHP搭配之最佳組合)如果找到了第#行,將停止
d:只要MySQL(和PHP搭配之最佳組合)已經(jīng)發(fā)送了第一個(gè)#行到客戶,MySQL(和PHP搭配之最佳組合)將放棄查詢
e:limit 0一直會(huì)很快的返回一個(gè)空集合.
f:臨時(shí)表的大小使用limit#計(jì)算需要多少空間來(lái)解決查詢
6:MySQL數(shù)據(jù)庫(kù)優(yōu)化insert
插入一條記錄的是由以下構(gòu)成:
a:連接(3)
b:發(fā)送查詢給服務(wù)器(2)
c:分析查詢(2)
d:插入記錄(1*記錄大?。?br />
e:插入索引(1*索引)
f:關(guān)閉(1)
以上數(shù)字可以看成和總時(shí)間成比例
改善插入速度的一些方法:
6.1:如果同時(shí)從一個(gè)連接插入許多行,使用多個(gè)值的insert,這比用多個(gè)語(yǔ)句要快
6.2:如果從不同連接插入很多行,使用insert delayed語(yǔ)句速度更快
6.3: 用myisam,如果在表中沒有刪除的行,能在select:s正在運(yùn)行的同時(shí)插入行
6.4: 當(dāng)從一個(gè)文本文件裝載一個(gè)表時(shí),用load data infile.這個(gè)通常比insert快20 倍
3.6:所有常數(shù)的表在查詢中在任何其他表之前讀出
3.7:對(duì)外聯(lián)結(jié)表最好聯(lián)結(jié)組合是嘗試了所有可能性找到的
3.8:如果有一個(gè)order by字句和一個(gè)不同的group by子句或者order by或者group by包含不是來(lái)自聯(lián)結(jié)的第一個(gè)表的列,那么創(chuàng)建一個(gè)臨時(shí)表
3.9:如果使用了sql_small_result,那么msyql使用在內(nèi)存中的一個(gè)表
3.10:每個(gè)表的索引給查詢并且使用跨越少于30%的行的索引.
3.11在每個(gè)記錄輸出前,跳過(guò)不匹配having子句的行
4:MySQL數(shù)據(jù)庫(kù)優(yōu)化left join
在MySQL(和PHP搭配之最佳組合)中 a left join b按以下方式實(shí)現(xiàn)
a:表b依賴于表a
b:表a依賴于所有用在left join條件的表(除了b)
c:所有l(wèi)eft join條件被移到where子句中
d:進(jìn)行所有的聯(lián)結(jié)優(yōu)化,除了一個(gè)表總是在所有他依賴的表后讀?。绻幸粋€(gè)循環(huán)依賴,那么將發(fā)生錯(cuò)誤
e:進(jìn)行所有的標(biāo)準(zhǔn)的where優(yōu)化 f:如果在a中有一行匹配where子句,但是在b中沒有任何匹配left join條件,那么,在b中生成的所有設(shè)置為NULL的一行
g:如果使用left join來(lái)找出某些表中不存在的行并且在where部分有column_name IS NULL測(cè)試(column_name為NOT NULL列).那么,MySQL(和PHP搭配之最佳組合)在它已經(jīng)找到了匹配left join條件的一行后,將停止在更多的行后尋找
5:MySQL數(shù)據(jù)庫(kù)優(yōu)化limit
a:如果用limit只選擇一行,當(dāng)MySQL(和PHP搭配之最佳組合)需要掃描整個(gè)表時(shí),它的作用相當(dāng)于索引
b:如果使用limit#與order by,MySQL(和PHP搭配之最佳組合)如果找到了第#行,將結(jié)束排序,而不會(huì)排序正個(gè)表
c:當(dāng)結(jié)合limit#和distinct時(shí),MySQL(和PHP搭配之最佳組合)如果找到了第#行,將停止
d:只要MySQL(和PHP搭配之最佳組合)已經(jīng)發(fā)送了第一個(gè)#行到客戶,MySQL(和PHP搭配之最佳組合)將放棄查詢
e:limit 0一直會(huì)很快的返回一個(gè)空集合.
f:臨時(shí)表的大小使用limit#計(jì)算需要多少空間來(lái)解決查詢
6:MySQL數(shù)據(jù)庫(kù)優(yōu)化insert
插入一條記錄的是由以下構(gòu)成:
a:連接(3)
b:發(fā)送查詢給服務(wù)器(2)
c:分析查詢(2)
d:插入記錄(1*記錄大小)
e:插入索引(1*索引)
f:關(guān)閉(1)
以上數(shù)字可以看成和總時(shí)間成比例
改善插入速度的一些方法:
6.1:如果同時(shí)從一個(gè)連接插入許多行,使用多個(gè)值的insert,這比用多個(gè)語(yǔ)句要快
6.2:如果從不同連接插入很多行,使用insert delayed語(yǔ)句速度更快
6.3: 用myisam,如果在表中沒有刪除的行,能在select:s正在運(yùn)行的同時(shí)插入行
6.4: 當(dāng)從一個(gè)文本文件裝載一個(gè)表時(shí),用load data infile.這個(gè)通常比insert快20 倍
6.5:可以鎖定表然后插入--主要的速度差別是在所有insert語(yǔ)句完成后,索引緩沖區(qū)僅被存入到硬盤一次.一般與有不同的insert語(yǔ)句那樣多次存入要快.如果能用一個(gè)單個(gè)語(yǔ)句插入所有的行,鎖定就不需要.鎖定也降低連接的整體時(shí)間.但是對(duì)某些線程最大等待時(shí)間將上升.例如
- thread 1 does 1000 inserts
- thread 2,3 and 4 does 1 insert
- thread 5 does 1000 inserts
如果不使用鎖定,2,3,4將在1和5之前完成.如果使用鎖定,2,3,4,將可能在1和5之后完成.但是整體時(shí)間應(yīng)該快40%.因?yàn)閕nsert,update,delete操作在MySQL(和PHP搭配之最佳組合)中是很快的,通過(guò)為多于大約5次連續(xù)不斷的插入或更新一行的東西加鎖,將獲得更好的整體性能.
如果做很多一行的插入,可以做一個(gè)lock tables,偶爾隨后做一個(gè)unlock tables(大約每1000行)以允許另外的線程存取表.這仍然將導(dǎo)致獲得好的性能.load data infile對(duì)裝載數(shù)據(jù)仍然是很快的.
為了對(duì)load data infile和insert得到一些更快的速度,擴(kuò)大關(guān)鍵字緩沖區(qū).
7優(yōu)化update的速度
它的速度依賴于被更新數(shù)據(jù)的大小和被更新索引的數(shù)量
使update更快的另一個(gè)方法是推遲修改,然后一行一行的做很多修改.如果鎖定表,做一行一行的很多修改比一次做一個(gè)快
8MySQL數(shù)據(jù)庫(kù)優(yōu)化delete速度
刪除一個(gè)記錄的時(shí)間與索引數(shù)量成正比.為了更快的刪除記錄,可以增加索引緩存的大小 從一個(gè)表刪除所有行比刪除這個(gè)表的大部分要快的多
【編輯推薦】