国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
MySQL優(yōu)化(四) MySQL 卓越資源

MySQL優(yōu)化(四)

2007-06-24 23:22 來(lái)源: imysql.cn 作者:葉金榮 網(wǎng)友評(píng)論 0 條 瀏覽次數(shù) 64

7.2.9 MySQL 如何優(yōu)化 ORDER BY

 

在一些情況下,MySQL可以直接使用索引來(lái)滿(mǎn)足一個(gè) ORDER BYGROUP BY 子句而無(wú)需做額外的排序。

盡管 ORDER BY 不是和索引的順序準(zhǔn)確匹配,索引還是可以被用到,只要不用的索引部分和所有的額外的 ORDER BY 字段在 WHERE 子句中都被包括了。下列的幾個(gè)查詢(xún)都會(huì)使用索引來(lái)解決 ORDER BYGROUP BY 部分:

SELECT * FROM t1 ORDER BY key_part1,key_part2,... ;SELECT * FROM t1 WHERE key_part1=constant ORDER BY key_part2;SELECT * FROM t1 WHERE key_part1=constant GROUP BY key_part2;SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 DESC;SELECT * FROM t1WHERE key_part1=1 ORDER BY key_part1 DESC, key_part2 DESC;

在另一些情況下,MySQL無(wú)法使用索引來(lái)滿(mǎn)足 ORDER BY,盡管它會(huì)使用索引來(lái)找到記錄來(lái)匹配 WHERE 子句。這些情況如下:


  • 對(duì)不同的索引鍵做 ORDER BY

     

    SELECT * FROM t1 ORDER BY key1, key2;

     

  • 在非連續(xù)的索引鍵部分上做 ORDER BY

     

    SELECT * FROM t1 WHERE key2=constant ORDER BY key_part2;

     

  • 同時(shí)使用了 ASCDESC

     

    SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;

     

  • 用于搜索記錄的索引鍵和做 ORDER BY 的不是同一個(gè):

     

    SELECT * FROM t1 WHERE key2=constant ORDER BY key1;

     

  • 有很多表一起做連接,而且讀取的記錄中在 ORDER BY 中的字段都不全是來(lái)自第一個(gè)非常數(shù)的表中(也就是說(shuō),在 EXPLAIN 分析的結(jié)果中的第一個(gè)表的連接類(lèi)型不是 const)。

     

     

  • 使用了不同的 ORDER BYGROUP BY 表達(dá)式。

     

     

  • 表索引中的記錄不是按序存儲(chǔ)。例如,HASHHEAP 表就是這樣。

 

通過(guò)執(zhí)行 EXPLAIN SELECT ... ORDER BY,就知道MySQL是否在查詢(xún)中使用了索引。如果 Extra 字段的值是 Using filesort,則說(shuō)明MySQL無(wú)法使用索引。詳情請(qǐng)看"7.2.1 EXPLAIN Syntax (Get Information About a SELECT)"。

當(dāng)必須對(duì)結(jié)果進(jìn)行排序時(shí),MySQL 4.1 以前它使用了以下 filesort 算法:


  1. 根據(jù)索引鍵讀取記錄,或者掃描數(shù)據(jù)表。那些無(wú)法匹配 WHERE 分句的記錄都會(huì)被略過(guò)。

     

     

  2. 在緩沖中每條記錄都用一個(gè)‘對(duì)’存儲(chǔ)了2個(gè)值(索引鍵及記錄指針)。緩沖的大小依據(jù)系統(tǒng)變量 sort_buffer_size 的值而定。

     

     

  3. 當(dāng)緩沖慢了時(shí),就運(yùn)行 qsort(快速排序)并將結(jié)果存儲(chǔ)在臨時(shí)文件中。將存儲(chǔ)的塊指針保存起來(lái)(如果所有的‘對(duì)’值都能保存在緩沖中,就無(wú)需創(chuàng)建臨時(shí)文件了)。

     

     

  4. 執(zhí)行上面的操作,直到所有的記錄都讀取出來(lái)了。

     

     

  5. 做一次多重合并,將多達(dá) MERGEBUFF(7)個(gè)區(qū)域的塊保存在另一個(gè)臨時(shí)文件中。重復(fù)這個(gè)操作,直到所有在第一個(gè)文件的塊都放到第二個(gè)文件了。

     

     

  6. 重復(fù)以上操作,直到剩余的塊數(shù)量小于 MERGEBUFF2 (15)。

     

     

  7. 在最后一次多重合并時(shí),只有記錄的指針(排序索引鍵的最后部分)寫(xiě)到結(jié)果文件中去。

     

     

  8. 通過(guò)讀取結(jié)果文件中的記錄指針來(lái)按序讀取記錄。想要優(yōu)化這個(gè)操作,MySQL將記錄指針讀取放到一個(gè)大的塊里,并且使用它來(lái)按序讀取記錄,將記錄放到緩沖中。緩沖的大小由系統(tǒng)變量 read_rnd_buffer_size 的值而定。這個(gè)步驟的代碼在源文件 `sql/records.cc' 中。

 

這個(gè)逼近算法的一個(gè)問(wèn)題是,數(shù)據(jù)庫(kù)讀取了2次記錄:一次是估算 WHERE 分句時(shí),第二次是排序時(shí)。盡管第一次都成功讀取記錄了(例如,做了一次全表掃描),第二次是隨機(jī)的讀取(索引鍵已經(jīng)排好序了,但是記錄并沒(méi)有)。

在MySQL 4.1 及更新版本中,filesort 優(yōu)化算法用于記錄中不只包括索引鍵值和記錄的位置,還包括查詢(xún)中要求的字段。這么做避免了需要2次讀取記錄。改進(jìn)的 filesort 算法做法大致如下:

     

     

  1. 跟以前一樣,讀取匹配 WHERE 分句的記錄。

     

     

  2. 相對(duì)于每個(gè)記錄,都記錄了一個(gè)對(duì)應(yīng)的;‘元組’信息信息,包括索引鍵值、記錄位置、以及查詢(xún)中所需要的所有字段。

     

     

  3. 根據(jù)索引鍵對(duì)‘元組’信息進(jìn)行排序。

     

     

  4. 按序讀取記錄,不過(guò)是從已經(jīng)排序過(guò)的‘元組’列表中讀取記錄,而非從數(shù)據(jù)表中再讀取一次。

 

使用改進(jìn)后的 filesort 算法相比原來(lái)的,‘元組’比‘對(duì)’需要占用更長(zhǎng)的空間,它們很少正好適合放在排序緩沖中(緩沖的大小是由 sort_buffer_size 的值決定的)。因此,這就可能需要有更多的I/O操作,導(dǎo)致改進(jìn)的算法更慢。為了避免使之變慢,這種優(yōu)化方法只用于排序‘元組’中額外的字段的大小總和超過(guò)系統(tǒng)變量 max_length_for_sort_data 的情況(這個(gè)變量的值設(shè)置太高的一個(gè)表象就是高磁盤(pán)負(fù)載低CPU負(fù)載)。

想要提高 ORDER BY 的速度,首先要看MySQL能否使用索引而非額外的排序過(guò)程。如果不能使用索引,可以試著遵循以下策略:


  • 增加 sort_buffer_size 的值。

     

     

  • 增加 read_rnd_buffer_size 的值。

     

     

  • 修改 tmpdir,讓它指向一個(gè)有很多剩余空間的專(zhuān)用文件系統(tǒng)。如果使用MySQL 4.1或更新,這個(gè)選項(xiàng)允許有多個(gè)路徑用循環(huán)的格式。各個(gè)路徑之間在 Unix 上用冒號(hào)(':')分隔開(kāi)來(lái),在 Windows,NetWare以及OS/2 上用分號(hào)(';')。可以利用這個(gè)特性將負(fù)載平均分?jǐn)偨o幾個(gè)目錄。注意:這些路徑必須是分布在不同物理磁盤(pán)上的目錄,而非在同一個(gè)物理磁盤(pán)上的不同目錄。


默認(rèn)情況下,MySQL也會(huì)對(duì)所有的 GROUP BY col1, col2, ... 查詢(xún)做排序,跟 ORDER BY col1, col2, ... 查詢(xún)一樣。如果顯式地包含一個(gè)有同樣字段列表的 ORDER BY 分句,MySQL優(yōu)化它的時(shí)候并不會(huì)損失速度,因?yàn)榕判蚩偸菚?huì)發(fā)生。如果一個(gè)查詢(xún)中包括 GROUP BY,但是想要避免對(duì)結(jié)果排序的開(kāi)銷(xiāo),可以通過(guò)使用 ORDER BY NULL 來(lái)取消排序。例如:

 

INSERT INTO fooSELECT a, COUNT(*) FROM bar GROUP BY a ORDER BY NULL;

 

7.2.10 MySQL 如何優(yōu)化 LIMIT


在一些情況下,MySQL在碰到一個(gè)使用 LIMIT row_count 但沒(méi)使用 HAVING
的查詢(xún)時(shí)會(huì)做不同的處理:

     

     

  • 如果只是用 LIMIT 來(lái)取得很少的一些記錄, MySQL 有時(shí)會(huì)使用索引,但是更通常的情況是做一個(gè)全表掃描。

     

     

  • 如果 LIMIT row_countORDER BY 一起使用,則MySQL在找到 row_count 條記錄后就會(huì)停止排序了,而非對(duì)整個(gè)表進(jìn)行排序。

     

     

  • 當(dāng) LIMIT row_countDISTINCT 一起聯(lián)合起來(lái)時(shí),MySQL在找到 row_count 條唯一記錄后就不再搜索了。

     

     

  • 在某些情況下, GROUP BY 可以通過(guò)按照順序讀取索引鍵來(lái)實(shí)現(xiàn)(或者在索引鍵上做排序)并且計(jì)算累計(jì)信息直到索引鍵改變了。在這種情況下,LIMIT row_count 不會(huì)計(jì)算任何非必須的 GROUP BY 值。

     

     

  • 一旦MySQL將請(qǐng)求的記錄全數(shù)發(fā)送給客戶(hù)端后,它就中止查詢(xún)除非使用了 SQL_CALC_FOUND_ROWS

     

     

  • LIMIT 0 總是返回一個(gè)空的結(jié)果集。這對(duì)于檢查查詢(xún)或者取得結(jié)果字段的類(lèi)型非常有用。

     

     

  • 當(dāng)服務(wù)器使用臨時(shí)表來(lái)處理查詢(xún),則 LIMIT row_count 可以用來(lái)計(jì)算需要多少空間。

 

7.2.11 如何避免全表掃描


如果MySQL需要做一次全表掃描來(lái)處理查詢(xún)時(shí),在 EXPLAIN 的結(jié)果中 type 字段的值是 ALL。在以下幾種條件下,MySQL就會(huì)做全表掃描:

  • 數(shù)據(jù)表是在太小了,做一次全表掃描比做索引鍵的查找來(lái)得快多了。當(dāng)表的記錄總數(shù)小于10且記錄長(zhǎng)度比較短時(shí)通常這么做。

     

     

  • 沒(méi)有合適用于 ONWHERE 分句的索引字段。

     

     

  • 讓索引字段和常量值比較,MySQL已經(jīng)計(jì)算(基于索引樹(shù))到常量覆蓋了數(shù)據(jù)表的很大部分,因此做全表掃描應(yīng)該會(huì)來(lái)得更快。詳情請(qǐng)看"7.2.4 How MySQL Optimizes WHERE Clauses"。

     

     

  • 通過(guò)其他字段使用了一個(gè)基數(shù)很?。ê芏嘤涗浧ヅ渌饕I值)的索引鍵。這種情況下,MySQL認(rèn)為使用索引鍵需要大量查找,還不如全表掃描來(lái)得更快。


對(duì)于小表來(lái)說(shuō),全表掃描通常更合適。但是對(duì)大表來(lái)說(shuō),嘗試使用以下技術(shù)來(lái)避免讓優(yōu)化程序錯(cuò)誤地選擇全表掃描:

  • 執(zhí)行 ANALYZE TABLE tbl_name 更新要掃描的表的索引鍵分布。詳情請(qǐng)看"14.5.2.1 ANALYZE TABLE Syntax"。

     

     

  • 使用 FORCE INDEX 告訴MySQL,做全表掃描的話(huà)會(huì)比利用給定的索引更浪費(fèi)資源。詳情請(qǐng)看"14.1.7 SELECT Syntax"。

     

    SELECT * FROM t1, t2 FORCE INDEX (index_for_column)    WHERE t1.col_name=t2.col_name;

     

  • 啟動(dòng) mysqld 時(shí)使用參數(shù) --max-seeks-for-key=1000 或者執(zhí)行 SET max_seeks_for_key=1000 來(lái)告訴優(yōu)化程序,所有的索引都不會(huì)導(dǎo)致超過(guò)1000次的索引搜索。請(qǐng)查看章節(jié)"5.2.3 Server System Variables"。

 

7.2.12 加速 INSERT


插入一條記錄花費(fèi)的時(shí)間由以下幾個(gè)因素決定,后面的數(shù)字大致表示影響的比例:

     

     

  • 連接:(3)

     

     

  • 發(fā)送查詢(xún)給服務(wù)器:(2)

     

     

  • 解析查詢(xún):(2)

     

     

  • 插入記錄:(1 x 記錄大?。?

     

     

  • 插入索引:(1 x 索引數(shù)量)

     

     

  • 關(guān)閉:(1)

 

這里并沒(méi)有考慮初始化時(shí)打開(kāi)數(shù)據(jù)表的開(kāi)銷(xiāo),因?yàn)槊看芜\(yùn)行查詢(xún)只會(huì)做這么一次。

如果是 B-tree 索引的話(huà),隨著索引數(shù)量的增加,插入記錄的速度以 log N 的比例下降。

可以使用以下幾種方法來(lái)提高插入速度:

  • 如果要在同一個(gè)客戶(hù)端在同一時(shí)間內(nèi)插入很多記錄,可以使用 INSERT 語(yǔ)句附帶有多個(gè) VALUES 值。這種做法比使用單一值的 INSERT 語(yǔ)句快多了(在一些情況下比較快)。如果是往一個(gè)非空的數(shù)據(jù)表里增加記錄,可以調(diào)整變量 bulk_insert_buffer_size 的值使之更快。詳情請(qǐng)看"5.2.3 Server System Variables"。

     

     

  • 如果要從不同的客戶(hù)端中插入大量記錄,使用 INSERT DELAYED 語(yǔ)句也可以提高速度。詳情請(qǐng)看"14.1.4 INSERT Syntax"。

     

     

  • 對(duì) MyISAM 而言,可以在 SELECT 語(yǔ)句正在運(yùn)行時(shí)插入記錄,只要這時(shí)候沒(méi)有正在刪除記錄。

     

     

  • 想要將一個(gè)文本文件加載到數(shù)據(jù)表中,可以使用 LOAD DATA INFILE。這通常是使用大量 INSERT 語(yǔ)句的20倍。詳情請(qǐng)看"14.1.5 LOAD DATA INFILE Syntax"。

     

     

  • 通過(guò)一些額外的工作,就可能讓 LOAD DATA INFILE 在數(shù)據(jù)表有大量索引的情況下運(yùn)行的更快。步驟如下:
    1. CREATE TABLE 隨便創(chuàng)建一個(gè)表。

       

       

    2. 執(zhí)行 FLUSH TABLES 語(yǔ)句或 mysqladmin flush-tables 命令。

       

       

    3. 執(zhí)行 myisamchk --keys-used=0 -rq /path/to/db/tbl_name 命令,刪掉數(shù)據(jù)表的所有索引。

       

       

    4. 執(zhí)行 LOAD DATA INFILE,數(shù)據(jù)插入到表中,由于無(wú)需更新表索引,因此這將非常快。

       

       

    5. 如果將來(lái)只是讀取改表,運(yùn)行 myisampack 讓數(shù)據(jù)表變得更小點(diǎn)。詳情查看"15.1.3.3 Compressed Table Characteristics"。

       

       

    6. 運(yùn)行 myisamchk -r -q /path/to/db/tbl_name 重建索引。創(chuàng)建的索引樹(shù)在寫(xiě)入磁盤(pán)前先保存在內(nèi)存中,這省去了磁盤(pán)搜索,因此速度快多了。重建后的索引樹(shù)分布非常均衡。
    7. 執(zhí)行 FLUSH TABLES 語(yǔ)句或 mysqladmin flush-tables 命令。

    注意,LOAD DATA INFILE 將數(shù)據(jù)插入一個(gè)空表時(shí),也會(huì)做前接優(yōu)化;主要的不同在于:運(yùn)行 myisamchk 會(huì)分配更多的臨時(shí)內(nèi)存用于創(chuàng)建索引,而執(zhí)行 LOAD DATA INFILE 命令則是讓數(shù)據(jù)庫(kù)服務(wù)器分配內(nèi)存用于重建索引。從 MySQL 4.0 起,可以運(yùn)行 ALTER TABLE tbl_name DISABLE KEYS 來(lái)代替 myisamchk --keys-used=0 -rq /path/to/db/tbl_name,運(yùn)行 ALTER TABLE tbl_name ENABLE KEYS 代替 myisamchk -r -q /path/to/db/tbl_name。這么做就可以省去 FLUSH TABLES 步驟。

     

     

  • 可以在鎖表后,一起執(zhí)行幾個(gè)語(yǔ)句來(lái)加速 INSERT 操作:

     

    LOCK TABLES a WRITE;    INSERT INTO a VALUES (1,23),(2,34),(4,33);    INSERT INTO a VALUES (8,26),(6,29);    UNLOCK TABLES;

    這對(duì)性能提高的好處在于:直到所有的 INSERT 語(yǔ)句都完成之后,索引緩存一次性刷新到磁盤(pán)中。通常情況是,多有少次 INSERT 語(yǔ)句就會(huì)有多數(shù)次索引緩存刷新到磁盤(pán)中的開(kāi)銷(xiāo)。如果能在一個(gè)語(yǔ)句中一次性插入多個(gè)值的話(huà),顯示的鎖表操作也就沒(méi)必要了。對(duì)事務(wù)表而言,用 BEGIN/COMMIT 代替 LOCK TABLES 來(lái)提高速度。鎖表也回降低多次連接測(cè)試的總時(shí)間,盡管每個(gè)獨(dú)立連接為了等待鎖的最大等待時(shí)間也會(huì)增加。例如:

    Connection 1 does 1000 inserts    Connections 2, 3, and 4 do 1 insert    Connection 5 does 1000 inserts

    如果沒(méi)有鎖表,則連接2,3,4會(huì)在1,5之前就做完了。如果鎖表了,則連接2,3,4可能在1,5之后才能完成,但是總時(shí)間可能只需要40%。MySQL的 INSERT, UPDATE, DELETE 操作都非???,不過(guò)在一個(gè)語(yǔ)句中如果有超過(guò)5個(gè)插入或者更新時(shí)最好加鎖以得到更好的性能。如果要一次性做很多個(gè)插入,最好是在每個(gè)循環(huán)(大約1000次)的前后加上 LOCK TABLESUNLOCK TABLES,從而讓其他進(jìn)程也能訪(fǎng)問(wèn)數(shù)據(jù)表;這么做性能依然不錯(cuò)。INSERT 總是比 LOAD DATA INFILE 插入數(shù)據(jù)來(lái)得慢,因?yàn)槎叩膶?shí)現(xiàn)策略有著分明的不同。

  • 想要讓 MyISAM 表更快,在 LOAD DATA
    INFILE
    INSERT 時(shí)都可以增加系統(tǒng)變量 key_buffer_size 的值,詳情請(qǐng)看"7.5.2 Tuning Server Parameters"。

 

7.2.13 加速 UPDATE

 

UPDATE 語(yǔ)句的優(yōu)化和 SELECT 一樣,只不過(guò)它多了額外的寫(xiě)入開(kāi)銷(xiāo)。寫(xiě)入的開(kāi)銷(xiāo)取決于要更新的記錄數(shù)以及索引數(shù)。如果索引沒(méi)有發(fā)生變化,則就無(wú)需更新。

另一個(gè)提高更新速度的辦法是推遲更新并且把很多次更新放在后面一起做。如果鎖表了,那么同時(shí)做很多次更新比分別做更新來(lái)得快多了。

注意,如果是在 MyISAM 表中使用了動(dòng)態(tài)的記錄格式,那么記錄被更新為更長(zhǎng)之后就可能會(huì)被拆分。如果經(jīng)常做這個(gè),那么偶爾做一次 OPTIMIZE TABLE 就顯得非常重要了。詳情請(qǐng)看"14.5.2.5 OPTIMIZE TABLE Syntax"。

 

7.2.14 加速 DELETE

 

刪除單個(gè)記錄的時(shí)間和它的索引個(gè)數(shù)幾乎成正比。想更快地刪除記錄,可以增加索引鍵的緩存。詳情請(qǐng)看"7.5.2 Tuning Server Parameters"。

如果想要?jiǎng)h除數(shù)據(jù)表的所有記錄,請(qǐng)使用 TRUNCATE TABLE tbl_name 而不是 DELETE FROM tbl_name。詳情請(qǐng)看"14.1.9 TRUNCATE Syntax"。

7.2.15 其他優(yōu)化點(diǎn)子

本章節(jié)列出了一些改善查詢(xún)處理速度的其他點(diǎn)子:


  • 使用永久連接到數(shù)據(jù)庫(kù),避免連接的開(kāi)銷(xiāo)。如果需要初始化很多連接,而又不能用永久連接,那么可以修改變量 thread_cache_size 的值,詳情請(qǐng)看"7.5.2 Tuning Server Parameters"。

     

     

  • 總是檢查查詢(xún)是否利用了表中已有的索引。在MySQL中,可以用 EXPLAIN 語(yǔ)句來(lái)分析。詳情請(qǐng)看"7.2.1 EXPLAIN Syntax (Get Information About a SELECT)"。

     

     

  • 盡量不要在經(jīng)常需要更新的 MyISAM 表上用太過(guò)復(fù)雜的 SELECT 語(yǔ)句,這是為了避免在讀和寫(xiě)之間爭(zhēng)奪鎖。

     

     

  • MyISAM 表中,如果沒(méi)有正在刪除記錄,則可以在其他查詢(xún)正在讀取數(shù)據(jù)的同時(shí)插入記錄。如果這種情況十分重要,那么就要盡量在表沒(méi)有刪除記錄時(shí)才使用表。另一個(gè)可能的辦法就是在刪除一大堆記錄之后執(zhí)行 OPTIMIZE TABLE 語(yǔ)句。

     

     

  • 如果總是需要按照 expr1, expr2, ... 的順序取得記錄,那么請(qǐng)使用 ALTER TABLE ... ORDER BY expr1, expr2, ... 修改表。通過(guò)這種方法擴(kuò)充修改表之后,就可能獲得更高的性能表現(xiàn)。

     

     

  • 在一些情況下,讓一個(gè)字段類(lèi)型是 ``hashed`` ,它基于其他字段信息。如果這個(gè)字段比較短而且基本上都是唯一值的話(huà),那么就可能會(huì)比在幾個(gè)字段上使用一個(gè)大索引來(lái)得更快,很簡(jiǎn)單的就能使用這樣的額外字段,如下:

     

    SELECT * FROM tbl_name WHERE hash_col=MD5(CONCAT(col1,col2))    AND col1='constant' AND col2='constant';

     

  • 如果 MyISAM 表經(jīng)常大量修改,那么要盡量避免修改所有的變長(zhǎng)字段(VARCHAR, BLOB,TEXT)。盡管表中只有一個(gè)變長(zhǎng)字段,它也會(huì)采用動(dòng)態(tài)記錄格式的。詳情請(qǐng)看"15 MySQL Storage Engines and Table Types"。

     

     

  • 通常情況下,當(dāng)數(shù)據(jù)表記錄變 ``大`` 之后,將表拆分成幾個(gè)不同的表并沒(méi)有多大用處。訪(fǎng)問(wèn)一條記錄是最大的性能點(diǎn)在于磁盤(pán)搜索時(shí)找到記錄的第一個(gè)字節(jié)上。只要找到記錄的位置后,現(xiàn)在的大部分磁盤(pán)對(duì)于大部分的應(yīng)用程序來(lái)說(shuō)都能很快的讀取到記錄。將 MyISAM 表拆分成多個(gè)唯一有關(guān)系的情況是,數(shù)據(jù)表中動(dòng)態(tài)格式的字段(見(jiàn)上)就可以被修改成固定大小的記錄,或者需要頻繁的掃描表,但是卻不需要讀取出大部分的字段。詳情請(qǐng)看"15 MySQL Storage Engines and Table Types"。

     

     

  • 如果需要頻繁的對(duì)一個(gè)表做基于很多字段信息的統(tǒng)計(jì)信息的話(huà),那么可能新建一個(gè)表來(lái)存儲(chǔ)這些實(shí)時(shí)更新的統(tǒng)計(jì)結(jié)果會(huì)更好。類(lèi)似下面的更新就會(huì)非??炝耍?

     

    UPDATE tbl_name SET count_col=count_col+1 WHERE key_col=constant;

    如果只需要表級(jí)鎖(多個(gè)讀/一個(gè)寫(xiě)),那么采用 MyISAM 存儲(chǔ)引擎就非常重要了,例如 MyISAMISAM 表。這在很多的數(shù)據(jù)庫(kù)中也會(huì)有不錯(cuò)的性能表現(xiàn),因?yàn)樾屑?jí)鎖管理程序在這種情況下也基本上沒(méi)什么用。

     

  • 如果需要從很大的日志表中搜集統(tǒng)計(jì)信息的話(huà),可以用摘要表來(lái)代替掃描整個(gè)日志表。維護(hù)摘要表比保持 ``實(shí)時(shí)`` 的統(tǒng)計(jì)信息來(lái)得更快。當(dāng)事情發(fā)生變化時(shí)(比如商業(yè)決策),重新建里摘要表比修改運(yùn)營(yíng)中的應(yīng)用程序快多了。

     

     

  • 如果可能,最好是分類(lèi)報(bào)告 ``實(shí)時(shí)`` 還是 ``統(tǒng)計(jì)`` 的,報(bào)告所需要的數(shù)據(jù)只需要來(lái)自摘要表,摘要表的信息則是周期的從實(shí)時(shí)數(shù)據(jù)中產(chǎn)生。

     

     

  • 應(yīng)該認(rèn)識(shí)到一個(gè)優(yōu)點(diǎn)就是字段有默認(rèn)值。當(dāng)要插入的值和默認(rèn)值不一致時(shí)才需要明確指定。這就省去了MySQL需要來(lái)提高插入速度這步了。

     

     

  • 在一些情況下,將數(shù)據(jù)組裝存儲(chǔ)在 BLOB 類(lèi)型字段中更方便。那么在應(yīng)用程序中就需要增加額外的命令來(lái)組裝和拆開(kāi) BLOB 字段中的值,不過(guò)這么做在一些時(shí)候就可以節(jié)省很多存儲(chǔ)開(kāi)銷(xiāo)。這在數(shù)據(jù)無(wú)需遵從 記錄-和-字段 格式的表結(jié)構(gòu)是很實(shí)用。

     

     

  • 通常地,應(yīng)該保存所有的冗余數(shù)據(jù)(在數(shù)據(jù)庫(kù)原理中叫做"第三范式")。然而,為了能取得更高的效率復(fù)制一些信息或者創(chuàng)建摘要表也是劃算的。

     

     

  • 存儲(chǔ)過(guò)程或者 UDFs(用戶(hù)定義函數(shù)) 的方式在執(zhí)行一些任務(wù)時(shí)可能性能更高。盡管如此,當(dāng)數(shù)據(jù)庫(kù)不支持這些特性時(shí),還是有其他的替代方法可以達(dá)到目的,即使它們有點(diǎn)慢。

     

     

  • 可以從查詢(xún)緩存或應(yīng)答中取得結(jié)果,然后將很多次的插入及更新操作放在一起做。如果數(shù)據(jù)庫(kù)支持表鎖(如MySQL和ORACLE),那么這就可以確保索引緩存在所有的更新操作之后只需要刷新一次。

     

     

  • 當(dāng)不需要直到數(shù)據(jù)什么時(shí)候?qū)懭氡碇袝r(shí),可以用 INSERT DELAYED。這就會(huì)提高速度,因?yàn)槎鄺l記錄同時(shí)在一起做一次磁盤(pán)寫(xiě)入操作。

     

  • 當(dāng)想讓 SELECT 語(yǔ)句的優(yōu)先級(jí)比插入操作還高時(shí),用 INSERT LOW_PRIORITY。

     

  • SELECT HIGH_PRIORITY 來(lái)使檢索記錄跳過(guò)隊(duì)列,也就是說(shuō)即使有其他客戶(hù)端正要寫(xiě)入數(shù)據(jù),也會(huì)先讓 SELECT 執(zhí)行完。

     

  • 在一條 INSERT 語(yǔ)句中采用多重記錄插入格式(很多數(shù)據(jù)庫(kù)都支持)。

     

  • LOAD DATA INFILE 來(lái)導(dǎo)入大量數(shù)據(jù),這比 INSERT 快。

     

  • AUTO_INCREMENT 字段來(lái)生成唯一值。

     

  • 定期執(zhí)行 OPTIMIZE TABLE 防止使用動(dòng)態(tài)記錄格式的 MyISAM 表產(chǎn)生碎片。詳情請(qǐng)看"15.1.3 MyISAM Table Storage Formats"。

     

  • 采用 HEAP 表,它可能會(huì)提高速度。詳情請(qǐng)看"15.1.3 MyISAM Table Storage Formats"。

     

  • 正常的WEB服務(wù)器配置中,圖片文件最好以文件方式存儲(chǔ),只在數(shù)據(jù)庫(kù)中保存文件的索引信息。這么做的原因是,通常情況下WEB服務(wù)器對(duì)于文件的緩存總是做的比數(shù)據(jù)庫(kù)來(lái)得好,因此使用文件存儲(chǔ)會(huì)讓系統(tǒng)更容易變得更快。

     

  • 對(duì)于頻繁訪(fǎng)問(wèn)的不是很重要的數(shù)據(jù),可以保存在內(nèi)存表中,例如對(duì)那些web客戶(hù)端不能保存cookies時(shí)用于保存最后一次顯示的標(biāo)題等信息。

     

  • 在不同表中值相同的字段應(yīng)該將它們聲明為一樣的類(lèi)型。在 MySQL 3.23 之前,不這么做的話(huà)在表連接時(shí)就會(huì)比較慢。讓字段名盡可能簡(jiǎn)單,例如,在一個(gè)叫做 customer 的表中,用 name 來(lái)代替 customer_name 作為字段名。為了讓字段名在其他數(shù)據(jù)庫(kù)系統(tǒng)中也能移植,應(yīng)該保持在18個(gè)字符長(zhǎng)度以?xún)?nèi)。

     

  • 如果需要真正的高速,建議看看各種數(shù)據(jù)庫(kù)服務(wù)器支持的底層數(shù)據(jù)存儲(chǔ)接口之間的區(qū)別。例如,通過(guò)直接訪(fǎng)問(wèn)MySQL的 MyISAM 存儲(chǔ)引擎,會(huì)比通過(guò)其他的SQL接口快2-5倍。這要求數(shù)據(jù)必須和應(yīng)用程序在同一個(gè)服務(wù)器上,并且它通常只被一個(gè)進(jìn)程訪(fǎng)問(wèn)(因?yàn)橥獠课募i確實(shí)慢)。只用一個(gè)進(jìn)程就可以消除在MySQL服務(wù)器上引入底層的 MyISAM 指令引發(fā)的問(wèn)題了(這容易獲得更高性能,如果需要的話(huà))。由于數(shù)據(jù)庫(kù)接口設(shè)計(jì)的比較細(xì)心,就很容易支持這種優(yōu)化方式了。

     

  • 如果使用數(shù)字型數(shù)據(jù)的話(huà),在很多情況下想要訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)(使用在線(xiàn)連接)的信息會(huì)比采用文本文件來(lái)得快。由于數(shù)字型信息相比文本文件在數(shù)據(jù)庫(kù)中存儲(chǔ)的更加緊湊,因此訪(fǎng)問(wèn)時(shí)只需要更少的磁盤(pán)搜索。而且在應(yīng)用程序中也可以節(jié)省代碼,因?yàn)闊o(wú)需解析文本文件以找到對(duì)應(yīng)的行和字段。

     

  • 數(shù)據(jù)庫(kù)復(fù)制對(duì)一些操作會(huì)有性能上的益處??梢詫⒖蛻?hù)端從多個(gè)復(fù)制服務(wù)器上取得數(shù)據(jù),這就能將負(fù)載分?jǐn)偭恕榱吮苊鈧浞輸?shù)據(jù)時(shí)會(huì)讓主服務(wù)器變慢,還可以將備份放在從服務(wù)器上。詳情請(qǐng)看"6 Replication in MySQL"。

     

  • 定義 MyISAM 表時(shí)增加選項(xiàng) DELAY_KEY_WRITE=1,這樣的話(huà)就會(huì)另索引更新更快,因?yàn)橹挥械鹊綌?shù)據(jù)表關(guān)閉了才會(huì)刷新磁盤(pán)。不過(guò)缺點(diǎn)是可能會(huì)在數(shù)據(jù)表還打開(kāi)時(shí)服務(wù)器被殺死,可以使用參數(shù) --myisam-recover 來(lái)保證數(shù)據(jù)的安全,或者在數(shù)據(jù)庫(kù)重啟前運(yùn)行 myisamchk 命令(盡管如此,在這種情況下,使用 DELAY_KEY_WRITE 的話(huà)也不會(huì)丟失任何東西,因?yàn)樗饕偸强梢詮臄?shù)據(jù)中重新生成)。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
這38個(gè)小技巧告訴你如何快速學(xué)習(xí)MySQL數(shù)據(jù)庫(kù)
MySQL在大數(shù)據(jù)、高并發(fā)場(chǎng)景下的SQL語(yǔ)句優(yōu)化和''''最佳實(shí)踐''''
MySQL數(shù)據(jù)庫(kù)性能優(yōu)化
PHP教程(13)mysql數(shù)據(jù)庫(kù)備份+事物操作+觸發(fā)器+用戶(hù)管理
MySQL數(shù)據(jù)庫(kù)基礎(chǔ)與實(shí)戰(zhàn)應(yīng)用
Oracle的索引類(lèi)型及使用技巧
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服