本論文在其他論文欄目,由論文格式網整理,轉載請注明來源www.donglienglish.cn,更多論文,請點論文格式范文查看
SQL數據庫可高效處理成批和成組的數據,而對于單個數據處理則效率低下,因此,在編寫客戶端程序時,應盡量將數據成批(成組)地送往數據庫,或成批(成組)地查詢數據。另外,在客戶端,使用SQL語句也存在優化問題。如:
dim mValue as Single, strSQL as string
mValue=12.34
strSQL=”UPDATE tablename SET value = “+str(mValue)+” WHERE name=’Generator’”
SQLExecDirect(語句句柄, strSQL ,SQL_NTS);
該語句將表tablename中name=’ Generator’記錄的value值更新為12.34,該操作在程序運行中經過兩次轉換,首先將單精度數轉換為字符串,和其他字符串合并后傳遞給ODBC 驅動程序,驅動程序又將字符串再轉換為ODBC特有的數據格式,如更新大量數據則花費在轉換數據格式上的系統開銷很大,應盡量避免編寫上述代碼。對于多次常用語句應進行語句準備,以后可多次使用。
一般來說,針對有大量重復值、且經常有范圍查詢(between, >,< ,>=,< =)和order by、group by發生的列,建立非缺省的群集索引可能會使性能更佳,而對于經常同時存取多列,且每列都含有重復值的情況可考慮建立組合索引,注意組合索引要盡量使關鍵查詢形成索引覆蓋,其前導列一定要是使用最頻繁的列。
在進行多表操作時,可在執行前根據連接條件,使用查詢優化器列出幾組可能的連接方案并從中找出系統開銷最小的最佳方案。連接條件要充分考慮帶有索引的表、行數多的表。內外表的選擇可由下列公式確定。其中乘積最小的方案為最佳。
乘積=外層表中的匹配行數*內層表中每一次查找的次數
在where子句中,任何對列的操作都將導致表掃描,這些操作包括數據庫函數、計算表達式等等,查詢時要盡可能將操作移至等號右邊。假設有如下兩個SQL語句,其條件語句中的列value已建有恰當的索引
語句1:select * from Table1 where value/30<100
語句2:select * from Table1 where value<100*30
在表中數據很多時,可明顯看出語句2的運行速度比語句1快得多,這是因為where子句中對列的任何操作結果都是在SQL運行時逐列計算得到的,因此它不得不進行表搜索,而沒有使用已建在該列上的索引。如果在查詢編譯時就能得到這些列的操作結果,那么就可以被SQL優化器優化,從而使用索引,避免表搜索,如語句2所示。
在where條件中in、or子句常會使用臨時數據庫的工作表,使索引失效;如果子句拆開后不產生大量重復值,可以考慮把子句拆開來優化運行,拆開的子句中應該包含索引。例如,假設在表Parts中有200000行記錄,在類型字段Type上有非群集索引,則針對SQL語句:select count(amount) from Parts where Type in('0','1'),因為其where條件中的'in'在邏輯上相當于'or',所以語法分析器會將in ('0','1')轉化為Type ='0' or Type ='1'來執行。我們原來期望它會根據每個or子句分別查找,再將結果相加,從而可以利用Type字段上的索引;但實際上它卻采用了"OR策略",即先取出滿足每個or子句的行,存入臨時數據庫的工作表中,再建立唯一索引以去掉重復行,最后從這個臨時表中計算結果。因此,實際過程沒有利用Type字段上的索引,并且完成時間還要受tempdb數據庫性能的影響。
SQL優化的實質就是在結果正確的前提下,用優化器可以識別的語句,盡量減少類型轉換和計算,充分利用索引,減少表掃描的I/O次數,盡量避免表搜索的發生。其實SQL的性能優化是一個復雜的過程,上述內容只是在應用層次的一些體現,深入研究還會涉及其它內容如數據庫層的資源配置、網絡層的流量控制以及操作系統層的總體設計等。
4 一個機器只用一個數據備存進程
在分布式的仿真與控制系統中,在同一個機器上經常運行多個進程,這些進程可能都需要進行數據保存工作。為了減少數據鏈接,減少網絡流量,同時增加系統的可靠性和運行的獨立性,可采用一個單獨的公用數據備存進程來承擔其它進程的數據保存功能。其它進程指向數據庫服務器的保存操作都通過該模塊進行。數據備存進程與其它應用程序進程之間的通訊可通過使用WM_COPYDATA消息進行傳輸,并使用SendMessage函數解決Windows在通過WM_COPYDATA消息傳遞期間不提供繼承同步方式的問題。在接受方完成數據拷貝前該函數不返回,這樣發送方就不可能刪除和修改數據。該函數的語法為SendMessage(hwnd,WM_COPYDATA,wParam,lParam),其中wParam為包含數據的窗口的句柄。lParam指向一個COPYDATASTRUCT的結構。
下面給出了應用程序進程向數據備存進程傳遞數據的具體函數。該函數共有兩個參數,第一個參數AppNo標識所在應用程序的序號,第二個參數為要傳遞到數據備存進程中的具體SQL語句。
void SendRequestToDBServer(long AppNo,const char strSQL[])
{
static char Data[1024];
COPYDATASTRUCT