使用nolock有3條原則:mysql
1.查詢的結果用於「插、刪、改」的不能加nolock; 2.查詢的表屬於頻繁發生頁分裂的,慎用nolock ; 3.使用臨時表同樣能夠保存「數據前影」,起到相似Oracle的undo表空間的功能,能採用臨時表提升併發性能的,不要用nolock。
不要有超過5個以上的錶鏈接(JOIN),考慮使用臨時表或表變量存放中間結果。少用子查詢,視圖嵌套不要過深,通常視圖嵌套不要超過2個爲宜。 sql
存儲過程是編譯好、優化過、而且被組織到一個執行規劃裏、且存儲在數據庫中的SQL語句,是控制流語言的集合,速度固然快。反覆執行的動態SQL,可使用臨時存儲過程,該過程(臨時表)被放在Tempdb中。數據庫
select a.personMemberID, * from chineseresume a,personmember b where personMemberID = b.referenceid and a.personMemberID = ‘JCNPRH39681’ (A = B ,B = ‘號碼’) 緩存
select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = ‘JCNPRH39681’ and b.referenceid = ‘JCNPRH39681’ (A = B ,B = ‘號碼’, A = ‘號碼’) 服務器
select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = ‘JCNPRH39681’ and a.personMemberID = ‘JCNPRH39681’ (B = ‘號碼’, A = ‘號碼’)網絡
1.索引的建立要與應用結合考慮,建議大的OLTP表不要超過6個索引; 2.儘量的使用索引字段做爲查詢條件,尤爲是聚簇索引,必要時能夠經過index index_name來強制指定索引; 3.避免對大表查詢時進行table scan,必要時考慮新建索引; 4.在使用索引字段做爲條件時,若是該索引是聯合索引,那麼必須使用到該索引中的第一個字段做爲條件時才能保證系統使用該索引,不然該索引將不會被使用; 5.要注意索引的維護,週期性重建索引,從新編譯存儲過程。
SELECT * FROM record WHERE substrINg(card_no,1,4)=’5378’ (13秒) 併發
SELECT * FROM record WHERE amount/30< 1000 (11秒) 函數
SELECT * FROM record WHERE convert(char(10),date,112)=’19991201’ (10秒) 高併發
分析: 性能
WHERE子句中對列的任何操做結果都是在SQL運行時逐列計算獲得的,所以它不得不進行表搜索,而沒有使用該列上面的索引。
若是這些結果在查詢編譯時就能獲得,那麼就能夠被SQL優化器優化,使用索引,避免表搜索,所以將SQL重寫成下面這樣:
SELECT * FROM record WHERE card_no like ‘5378%’ (< 1秒)
SELECT * FROM record WHERE amount< 1000*30 (< 1秒)
SELECT * FROM record WHERE date= ‘1999/12/01’ (< 1秒)
例如:列出上個月的每一天,我會用connect by去遞歸查詢一下,毫不會去用循環從上個月第一天到最後一天。
Oracle的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最後的表(基礎表 driving table)將被最早處理,在FROM子句中包含多個表的狀況下,你必須選擇記錄條數最少的表做爲基礎表。
若是有3個以上的錶鏈接查詢,那就須要選擇交叉表(intersection table)做爲基礎表,交叉表是指那個被其餘表所引用的表。
低效:
SELECT JOB , AVG(SAL)
FROM EMP
GROUP BY JOB
HAVING JOB =’PRESIDENT’
OR JOB =’MANAGER’
高效:
SELECT JOB , AVG(SAL)
FROM EMP
WHERE JOB =’PRESIDENT’
OR JOB =’MANAGER’
GROUP BY JOB
1.觸發一個觸發器,執行一個觸發器事件自己就是一個耗費資源的過程; 2.若是可以使用約束實現的,儘可能不要使用觸發器; 3.不要爲不一樣的觸發事件(Insert,Update和Delete)使用相同的觸發器; 4.不要在觸發器中使用事務型代碼。
1.表的主鍵、外鍵必須有索引; 2.數據量超過300的表應該有索引; 3.常常與其餘表進行鏈接的表,在鏈接字段上應該創建索引; 4.常常出如今Where子句中的字段,特別是大表的字段,應該創建索引; 5.索引應該建在選擇性高的字段上; 6.索引應該建在小字段上,對於大的文本字段甚至超長字段,不要建索引; 7.複合索引的創建須要進行仔細分析,儘可能考慮用單字段索引代替; 8.正確選擇複合索引中的主列字段,通常是選擇性較好的字段; 9.複合索引的幾個字段是否常常同時以AND方式出如今Where子句中?單字段查詢是否極少甚至沒有?若是是,則能夠創建複合索引;不然考慮單字段索引; 10.若是複合索引中包含的字段常常單獨出如今Where子句中,則分解爲多個單字段索引; 11.若是複合索引所包含的字段超過3個,那麼仔細考慮其必要性,考慮減小複合的字段; 12.若是既有單字段索引,又有這幾個字段上的複合索引,通常能夠刪除複合索引; 13.頻繁進行數據操做的表,不要創建太多的索引; 14.刪除無用的索引,避免對執行計劃形成負面影響; 15.表上創建的每一個索引都會增長存儲開銷,索引對於插入、刪除、更新操做也會增長處理上的開銷。另外,過多的複合索引,在有單字段索引的狀況下,通常都是沒有存在價值的;相反,還會下降數據增長刪除時的性能,特別是對頻繁更新的表來講,負面影響更大。 16.儘可能不要對數據庫中某個含有大量重複的值的字段創建索引。
使用慢查詢日誌去發現慢查詢,使用執行計劃去判斷查詢是否正常運行,老是去測試你的查詢看看是否他們運行在最佳狀態下。
長此以往性能總會變化,避免在整個表上使用count(*),它可能鎖住整張表,使查詢保持一致以便後續類似的查詢可使用查詢緩存,在適當的情形下使用GROUP BY而不是DISTINCT,在WHERE、GROUP BY和ORDER BY子句中使用有索引的列,保持索引簡單,不在多個索引中包含同一個列。
有時候MySQL會使用錯誤的索引,對於這種狀況使用USE INDEX,檢查使用SQL_MODE=STRICT的問題,對於記錄數小於5的索引字段,在UNION的時候使用LIMIT不是是用OR。
爲了不在更新前SELECT,使用INSERT ON DUPLICATE KEY或者INSERT IGNORE,不要用UPDATE去實現,不要使用MAX,使用索引字段和ORDER BY子句,LIMIT M,N實際上能夠減緩查詢在某些狀況下,有節制地使用,在WHERE子句中使用UNION代替子查詢,在從新啓動的MySQL,記得來溫暖你的數據庫,以確保數據在內存和查詢速度快,考慮持久鏈接,而不是多個鏈接,以減小開銷。
基準查詢,包括使用服務器上的負載,有時一個簡單的查詢能夠影響其餘查詢,當負載增長在服務器上,使用SHOW PROCESSLIST查看慢的和有問題的查詢,在開發環境中產生的鏡像數據中測試的全部可疑的查詢。
1.從二級複製服務器上進行備份; 2.在進行備份期間中止複製,以免在數據依賴和外鍵約束上出現不一致; 3.完全中止MySQL,從數據庫文件進行備份; 4.若是使用MySQL dump進行備份,請同時備份二進制日誌文件 – 確保複製沒有中斷; 5.不要信任LVM快照,這極可能產生數據不一致,未來會給你帶來麻煩; 6.爲了更容易進行單表恢復,以表爲單位導出數據——若是數據是與其餘表隔離的。 7.當使用mysqldump時請使用–opt; 8.在備份以前檢查和優化表; 9.爲了更快的進行導入,在導入時臨時禁用外鍵約束。; 10.爲了更快的進行導入,在導入時臨時禁用惟一性檢測; 11.在每一次備份後計算數據庫,表以及索引的尺寸,以便更夠監控數據尺寸的增加; 12.經過自動調度腳本監控複製實例的錯誤和延遲; 13.按期執行備份。
使用EXPLAIN關鍵字可讓你知道MySQL是如何處理你的SQL語句的。這能夠幫你分析你的查詢語句或是表結構的性能瓶頸。EXPLAIN的查詢結果還會告訴你你的索引主鍵被如何利用的,你的數據表是如何被搜索和排序的。
當你查詢表的有些時候,你已經知道結果只會有一條結果,但由於你可能須要去fetch遊標,或是你也許會去檢查返回的記錄數。
在這種狀況下,加上LIMIT 1能夠增長性能。這樣一來,MySQL數據庫引擎會在找到一條數據後中止搜索,而不是繼續日後查少下一條符合記錄的數據。
myisam:應用時以讀和插入操做爲主,只有少許的更新和刪除,而且對事務的完整性,併發性要求不是很高的。
InnoDB:事務處理,以及併發條件下要求數據的一致性。除了插入和查詢外,包括不少的更新和刪除。(InnoDB有效地下降刪除和更新致使的鎖定)。
對於支持事務的InnoDB類型的表來講,影響速度的主要緣由是AUTOCOMMIT默認設置是打開的,並且程序沒有顯式調用BEGIN 開始事務,
致使每插入一條都自動提交,嚴重影響了速度。能夠在執行SQL前調用begin,多條SQL造成一個事物(即便autocommit打開也能夠),將大大提升性能。
原則:更小一般更好,簡單就好,全部字段都得有默認值,儘可能避免null。
例如:數據庫表設計時候更小的佔磁盤空間儘量使用更小的整數類型。(mediumint就比int更合適)
好比時間字段:datetime和timestamp,datetime佔用8個字節,而timestamp佔用4個字節,只用了一半,而timestamp表示的範圍是1970—2037適合作更新時間
MySQL能夠很好的支持大數據量的存取,可是通常說來,數據庫中的表越小,在它上面執行的查詢也就會越快。
所以,在建立表的時候,爲了得到更好的性能,咱們能夠將表中字段的寬度設得儘量小。
例如:在定義郵政編碼這個字段時,若是將其設置爲CHAR(255),顯然給數據庫增長了沒必要要的空間。甚至使用VARCHAR這種類型也是多餘的,由於CHAR(6)就能夠很好的完成任務了。
一樣的,若是能夠的話,咱們應該使用MEDIUMINT而不是BIGIN來定義整型字段,應該儘可能把字段設置爲NOT NULL,這樣在未來執行查詢的時候,數據庫不用去比較NULL值。
對於某些文本字段,例如「省份」或者「性別」,咱們能夠將它們定義爲ENUM類型。由於在MySQL中,ENUM類型被看成數值型數據來處理,而數值型數據被處理起來的速度要比文本類型快得多。這樣,咱們又能夠提升數據庫的性能。