7.2.2 估算查詢性能
在大多數(shù)情況下,可以通過統(tǒng)計(jì)磁盤搜索次數(shù)來估算查詢的性能。對(duì)小表來說,通常情況下只需要搜索一次磁盤就能找到對(duì)應(yīng)的記錄(因?yàn)樗饕赡芤呀?jīng)緩存起來了)。對(duì)大表來說,大致可以這么估算,它使用b樹做索引,想要找到一條記錄大概需要搜索的次數(shù)為:log(row_count) / log(index_block_length / 3 * 2 / (index_length + data_pointer_length)) + 1。
在mysql中,一個(gè)索引塊通常是1024bytes,數(shù)據(jù)指針通常是4bytes。對(duì)于一個(gè)有500,000條記錄、索引長(zhǎng)度為3bytes(medium integer)的表來說,根據(jù)上面的公式計(jì)算得到需要做 log(500,000)/log(1024/3*2/(3+4)) + 1 = 4 次搜索。
這個(gè)表的索引大概需要 500,000 * 7 * 3/2 = 5.2mb的存儲(chǔ)空間(假定典型的索引緩沖區(qū)的2/3),因此應(yīng)該會(huì)有更多的索引在內(nèi)存中,并且可能只需要1到2次調(diào)用就能找到對(duì)應(yīng)的記錄。
對(duì)于寫來說,大概需要4次(甚至更多)搜索才能找到新的索引位置,更新記錄時(shí)通常需要2次搜索。
請(qǐng)注意,前面的討論中并沒有提到應(yīng)用程序的性能會(huì)因?yàn)閘og n的值越大而下降。只要所有的東西都能由操作系統(tǒng)或者sql服務(wù)器緩存起來,那么性能只會(huì)因?yàn)閿?shù)據(jù)表越大而稍微下降。當(dāng)數(shù)據(jù)越來越大之后,就不能全部放到緩存中去了,就會(huì)越來越慢了,除非應(yīng)用程序是被磁盤搜索約束的(它跟隨著的log n值增加而增加)。為了避免這種情況,可以在數(shù)據(jù)量增大以后也隨著增大索引緩存容量。對(duì) myisam 類型表來說,索引緩存容量是由系統(tǒng)變量 key_buffer_size 控制的。詳情請(qǐng)看"7.5.2 tuning server parameters"。
7.2.3 select 查詢的速度
通常情況下,想要讓一個(gè)比較慢的 select ... where 查詢變得更快的第一件事就是,先檢查看看是否可以增加索引。所有對(duì)不同表的訪問都通常使用索引。可以使用 explain 語句來判斷 select 使用了哪些索引。詳情請(qǐng)看"7.4.5 how mysql uses indexes"和"7.2.1 explain syntax (get information about a select)"。
以下是幾個(gè)常用的提高 myisam 表查詢速度的忠告:
想要讓mysql將查詢優(yōu)化的速度更快些,可以在數(shù)據(jù)表已經(jīng)加載完全部數(shù)據(jù)后執(zhí)行行 analyze table 或運(yùn)行 myisamchk --analyze 命令。它更新了每個(gè)索引部分的值,這個(gè)值意味著相同記錄的平均值(對(duì)于唯一索引來說,這個(gè)值則一直都是 1)。mysql就會(huì)在當(dāng)你使用基于一個(gè)非恒量表達(dá)式的兩表連接時(shí),根據(jù)這個(gè)值來決定使用哪個(gè)索引。想要查看結(jié)果,可以在分析完數(shù)據(jù)表后運(yùn)行 show index from tbl_name 查看 cardinality 字段的值。myisamchk --description --verbose 顯示了索引的分布信息。
想要根據(jù)一個(gè)索引來排序數(shù)據(jù),可以運(yùn)行 myisamchk --sort-index --sort-records=1 (如果想要在索引 1 上做排序)。這對(duì)于有一個(gè)唯一索引并且想根據(jù)這個(gè)索引的順序依次讀取記錄的話來說是一個(gè)提高查詢速度的好辦法。不過要注意的是,第一次在一個(gè)大表上做排序的話將會(huì)耗費(fèi)很長(zhǎng)時(shí)間。
7.2.4 mysql如何優(yōu)化 where 子句
這個(gè)章節(jié)講述了優(yōu)化程序如何處理 where 子句。例子中使用了 select 語句,但是在 delete 和 update 語句中對(duì) where 子句的優(yōu)化是一樣的。
注意,關(guān)于mysql優(yōu)化的工作還在繼續(xù),因此本章節(jié)還沒結(jié)束。mysql做了很多優(yōu)化工作,而不僅僅是文檔中提到的這些。
mysql的一些優(yōu)化做法如下:
去除不必要的括號(hào):
((a and b) and c or (((a and b) and (c and d))))
-> (a and b and c) or (a and b and c and d)
展開常量:
(a-> b>5 and b=c and a=5 去除常量條件(在展開常量時(shí)需要): (b>=5 and b=5) or (b=6 and 5=5) or (b=7 and 5=6) -> b=5 or b=6 常量表達(dá)示在索引中只計(jì)算一次
新聞熱點(diǎn)
疑難解答
圖片精選