1.資料的容量:1-3年內會大概多少條資料,每條資料大概多少位元組;
2.資料項目:是否有大欄位,那些欄位的值是否經常被更新;
3.資料查詢SQL條件:哪些資料項目的列名稱經常出現在WHERE、GROUP BY、ORDER BY子句中等;
4.資料更新類SQL條件:有多少列經常出現UPDATE或DELETE 的WHERE子句中;
5.SQL量的統計比,如:SELECT:UPDATE+DELETE:INSERT=多少?
6.預計大表及相關聯的SQL,每天總的執行量在何數量級?
7.表中的資料:更新為主的業務 還是 查詢為主的業務
8.打算採用什麼資料庫教程物理伺服器,以及資料庫伺服器架構?
9.並發如何?
10.儲存引擎選擇InnoDB還是MyISAM?
大致明白以上10個問題,至於如何設計此類的大表,應該什麼都清楚了!
至於最佳化若是指建立好的表,不能變動表結構的話,那建議InnoDB引擎,多利用點記憶體,減輕磁碟IO負載,因為IO往往是資料庫伺服器的瓶頸
另外對最佳化索引結構去解決效能問題的話,建議優先考慮修改類SQL語句,使他們更快些,不得已只靠索引組織圖的方式,當然此話前提是,
索引已經建立的非常好,若是讀為主,可以考慮開啟query_cache,
以及調整一些參數值:sort_buffer_size,read_buffer_size,read_rnd_buffer_size,join_buffer_size
其他人建議:
1. 索引, 避免掃描,基於主鍵的尋找,上億資料也是很快的;
2. 反範式化設計,以空間換時間,避免join,有些join操作可以在用代碼實現,沒必要用資料庫來實現;
1、只返回需要的資料
返回資料到用戶端至少需要資料庫提取資料、網路傳輸資料、用戶端接收資料以及用戶端處理資料等環節,如果返回不需要的資料,就會增加伺服器、網路和用戶端的無效勞動,其害處是顯而易見的,避免這類事件需要注意:
A、橫向來看,不要寫SELECT *的語句,而是選擇你需要的欄位。
B、縱向來看,合理寫WHERE子句,不要寫沒有WHERE的SQL語句。
C、注意SELECT INTO後的WHERE子句,因為SELECT INTO把資料插入到暫存資料表,這個過程會鎖定一些系統資料表,如果這個WHERE子句返回的資料過多或者速度太慢,會造成系統資料表長期鎖定,諸塞其他進程。
D、對於彙總查詢,可以用HAVING子句進一步限定返回的行。
2、盡量少做重複的工作
這一點和上一點的目的是一樣的,就是盡量減少無效工作,但是這一點的側重點在用戶端程式,需要注意的如下:
A、控制同一語句的多次執行,特別是一些基礎資料的多次執行是很多程式員很少注意的。
B、減少多次的資料轉換,也許需要資料轉換是設計的問題,但是減少次數是程式員可以做到的。
C、杜絕不必要的子查詢和串連表,子查詢在執行計畫一般解釋成外串連,多餘的串連錶帶來額外的開銷。
D、合并對同一表同一條件的多次UPDATE,比如
UPDATE EMPLOYEE SET FNAME=’HAIWER’ WHERE EMP_ID=’ VPA30890F’
UPDATE EMPLOYEE SET LNAME=’YANG’ WHERE EMP_ID=’ VPA30890F’
這兩個語句應該合并成以下一個語句
UPDATE EMPLOYEE SET FNAME=’HAIWER’,LNAME=’YANG’
WHERE EMP_ID=’ VPA30890F’
E、UPDATE操作不要拆成DELETE操作+INSERT操作的形式,雖然功能相同,但是效能差別是很大的。
F、不要寫一些沒有意義的查詢,比如: SELECT * FROM EMPLOYEE WHERE 1=2
3、注意事務和鎖
事務是資料庫應用中和重要的工具,它有原子性、一致性、隔離性、持久性這四個屬性,很多操作我們都需要利用事務來保證資料的正確性。在使用事務中我們需要做到盡量避免死結、盡量減少阻塞。具體以下方面需要特別注意:
A、事務操作過程要盡量小,能拆分的事務要拆分開來。
B、事務操作過程不應該有互動,因為互動等待的時候,事務並未結束,可能鎖定了很多資源。
C、事務操作過程要按同一順序訪問對象。
D、提高事務中每個語句的效率,利用索引和其他方法提高每個語句的效率可以有效地減少整個事務的執行時間。
E、盡量不要指定鎖類型和索引,SQL SERVER允許我們自己指定語句使用的鎖類型和索引,但是一般情況下,SQL SERVER最佳化器選擇的鎖類型和索引是在當前資料量和查詢條件下是最優的,我們指定的可能只是在目前情況下更有,但是資料量和資料分布在將來是會變化的。
F、查詢時可以用較低的隔離等級,特別是報表查詢的時候,可以選擇最低的隔離等級(未提交讀)。