反模式:外層查詢 Books,迴圈內對每筆再查 Authors (N+1 問題)。
oRs = oConn.Execute("SELECT * FROM Books")
While Not oRs.Eof
strSQL = "SELECT * FROM Authors WHERE AuthorID=" & oRs("AuthorID")
oRs2 = oConn.Execute(strSQL)
Response.Write oRs("Title") & ">>" & oRs2("Name") & "<br>"
oRs.MoveNext
Wend
優化:單一 JOIN 完成。
strSQL = "SELECT Books.Title, Authors.Name FROM Books JOIN Authors ON Authors.AuthorID = Books.AuthorID"
oRs = oConn.Execute(strSQL)
While Not oRs.Eof
Response.Write oRs("Title") & ">>" & oRs("Name") & "<br>"
oRs.MoveNext
Wend
較慢:開啟可更新 Recordset 再 Update。
oRs = oConn.Execute("SELECT * FROM Authors WHERE AuthorID=17", 3, 3) ' adOpenStatic, adLockOptimistic
oRs("Name") = "DarkMan"
oRs.Update
較快:直接執行 UPDATE 陳述式。
strSQL = "UPDATE Authors SET Name='DarkMan' WHERE AuthorID=17"
oConn.Execute strSQL
將多條 SQL 組成單一批次送往伺服器,減少網路往返,並滿足 ACID 需求。
strSQL = ""
strSQL = strSQL & "SET XACT_ABORT ON" & vbCrLf
strSQL = strSQL & "BEGIN TRANSACTION" & vbCrLf
strSQL = strSQL & "INSERT INTO orders(OrdID,CustID,OrdDat) VALUES('9999','1234',GETDATE())" & vbCrLf
strSQL = strSQL & "INSERT INTO orderRows(OrdID,OrdRow,Item,Qty) VALUES('9999','01','G4385',5)" & vbCrLf
strSQL = strSQL & "INSERT INTO orderRows(OrdID,OrdRow,Item,Qty) VALUES('9999','02','G4726',1)" & vbCrLf
strSQL = strSQL & "COMMIT TRANSACTION" & vbCrLf
strSQL = strSQL & "SET XACT_ABORT OFF" & vbCrLf
oConn.Execute(strSQL)
SET XACT_ABORT ON 確保遇錯自動回滾。
WHERE 子句常用欄位 → 優先建索引。ORDER BY、GROUP BY、JOIN ON 欄位 → 納入考量。VARCHAR 而非 CHAR。TEXT(255) 但實際常只存 20 字元,5 萬筆資料導致資料庫膨脹、I/O 變慢。改為 VARCHAR(255) 或適當長度。效能優化無銀彈:減少往返 (JOIN/批次)、避免伺服端游標、精準索引、精簡資料型別,配合執行計畫分析持續調校。