這是我在這里的第一個問題,請溫柔。
在作業中,我繼承了對 MS Access 資料庫的負責,這對我的部門至關重要。
該資料庫發展了 20 多年,添加、洗掉和更改了內容。很快,這是一個令人費解的混亂。VBA 代碼包含這樣的好東西,我不騙你:
Dim p, strText, A, B, C, d, E, F, G, H, i, j, K, L, M, N, O, Z, R, Q, kd, AfGb, T, LN, DC, EntBez, TP, pack, Press, Fehler, ksoll, Y, zeileninhalt, dateipfad, auslesezeile As String
我正在慢慢清理它,但是......無論如何:
問題
打開某些表單時速度很慢(加載時間為 7-10 秒)。我能夠將其縮小到這些表單的記錄源,它們都使用基本相同的查詢或它的變體。
用戶在主表單中輸入作業編號并按回車鍵。然后底層查詢根據唯一鍵 JobNr 從兩個表中提取資料。結果是一行包含此作業的所有資訊。這些資訊顯示在編輯器表單中,使用查詢作為記錄源。
資料庫分為前端和后端,t1和t2是后端表,每個表大約有20k個條目。后端位于公司服務器上的某個地方,前端保存在每個用戶計算機的本地。
這是查詢:
SELECT *
FROM t1
INNER JOIN t2 ON t1.JobNr = t2.JobNr
WHERE JobNr = [Forms]![Main]![JobNr];
t1
具有JobNr
作為主鍵,t2
具有ID
作為主鍵,JobNr
未編入索引。我想嘗試對其進行索引以期獲得更好的性能,但目前無法在繁忙的作業日對后端進行更改...
這個簡單的查詢對于它是什么來說是非常緩慢的。問題似乎是執行順序。Access 似乎不是從 t1 和 t2 獲取單個條目并將它們連接到單個資料集,而是首先將兩個 friggin 表作為一個整體連接起來,然后才查找用戶感興趣的單個資料集。
我無法找到決定執行順序的解決方案。我嘗試了不同的方法,比如用嵌套的 Selects 重寫 SQL 代碼,比如:
SELECT *
FROM
(SELECT * FROM t1
WHERE t1.JobNr = [Forms]![Main]![JobNr]) AS q1
INNER JOIN
(SELECT * FROM t2
WHERE t2.JobNr = [Forms]![Main]![JobNr]) AS q2 ON q1.JobNr = q2.JobNr;
還是慢...
我想嘗試WITH
對 SQL 代碼進行磁區,但這顯然不受 MS Access SQL 支持。
我嘗試在訪問中將查詢拆分為兩個查詢 q1 和 q2,分別從 t1 和 q2 中提取資料。t2 與第三個查詢 q3 連接這些假定的子集......無濟于事。q1 和 q2 分別以預期的資料結果運行得非常快,但 q3 通常需要 7-10 秒。
我正在使用的當前方法是運行 q1 和 q2 并將獲取的資料保存到兩個臨時表 tq1 和 tq??2,然后在最后一個查詢中加入它們。這非常有效,因為它可以快速加載資料并將其顯示在編輯器中(< 0.5 秒,萬歲!)。我現在面臨的問題是將用戶在編輯器表單中所做的任何更改更新到后端表 t1 和 t2 ......現在,關閉和重新打開作業/編輯器時,用戶更改不會發生并且丟失。
Soooo,我錯過了什么/做錯了什么?有沒有辦法在INNER JOIN
沒有整個臨時表解決方法的情況下快速進行此查詢?
如果沒有,我將如何從本地臨時表更新后端表?編輯器中的更改保存在臨時表中,直到通過重新打開編輯器被覆寫。
我已經添加了中間查詢,添加了 resp。臨時表的主鍵(這不能直接在創建表查詢中完成......)但是......
我還嘗試在關閉編??輯器時使用更新查詢,這似乎也不起作用,但我可能需要除錯那個,我不確定它現在是否會死掉任何東西......
對不起,文字太長!
誠摯的問候,并提前感謝您的任何幫助!
uj5u.com熱心網友回復:
最明顯的返工是將過濾器移動到連接中:
SELECT *
FROM t1
INNER JOIN t2 ON (t1.JobNr = t2.JobNr AND t2.JobNr = [Forms]![Main]![JobNr])
我的猜測是,如果您在 t1 或 t2 上進行過濾,這無關緊要,但是我的猜測也是 Access 足夠智能,可以在加入時進行過濾,而且這似乎是不正確的,因此請檢查一下。
對于更詳細的性能分析,查詢計劃往往會有所幫助。請參閱如何從 Access 2010 獲取查詢計劃 (showplan.out)?
當然,將 14 調整為您的版本號。
uj5u.com熱心網友回復:
您需要向 中添加唯一索引t2.JobNr
,最好將其設為主鍵。
在這一點上,其他一切都只是浪費時間。
為用戶設定退出前端的日期和時間,必要時將其踢出:強制所有用戶與 2010 Access 后端資料庫斷開連接
從長遠來看,從 Access 后端遷移到服務器后端(如免費的 SQL Server Express)將是一個好主意。
編輯:你有沒有試過如果你根本不做 JOIN 會發生什么?
SELECT *
FROM t1, t2
WHERE t1.JobNr = [Forms]![Main]![JobNr]
AND t2.JobNr = [Forms]![Main]![JobNr]
通常你想避免這種情況,但在這種情況下它可能會有所幫助。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/380738.html