2012-03-20 78 views
2

我有一個4M行的Access數據庫,每個數據庫表示一個單獨的客戶訂單。分組數據減慢查詢,儘管結果數量減少了25%

我需要從Excel運行查詢(我使用VBA)以便僅檢索REGION1中的客戶的訂單。

我嘗試以下(名稱應該是相當不言自明):

Sub Query() 

Dim cn As Object 
Dim strFile As String 
Dim strCon As String 
Dim strSQL As String 

strFile = "C:\Users\MyName\Desktop\DataBase.accdb" 
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFile 
Set cn = CreateObject("ADODB.Connection") 
Set rs = CreateObject("ADODB.Recordset") 
cn.Open strCon 

strSQL = "SELECT [CUSTOMER], [DATE], [REVENUE]" _ 
& "FROM [SALES DB]" _ 
& "WHERE [REGION]='REGION1'" 
rs.Open strSQL, cn, 0, 1 

Worksheets(1).Cells(2, 1).CopyFromRecordset rs 

rs.Close 
Set rs = Nothing 
cn.Close 
Set cn = Nothing 

End Sub 

這工作得很好,但它是一個有點慢,因爲它返回〜600K行。

所以我想:「誰在關心所有客戶訂單的詳細清單?我只需要每月的總量,這應該減少返回的行數,從而提高速度!」。

所以我改變了我的代碼:

strSQL = "SELECT [CUSTOMER], MONTH([DATE]), YEAR([DATE]), SUM([REVENUE])" _ 
& "FROM [SALES DB]" _ 
& "WHERE [REGION]='REGION1'" 
& "GROUP BY [CUSTOMER], MONTH([DATE]), YEAR([DATE])" 

如我所料,現在只〜450K結果中。事情是,查詢實際上變慢了。

我實際上最好提取未分組的數據,然後用一個簡單的數據透視表進行聚合。

如何減少數據提取速度?我知道有一些計算需要在兩者之間進行,但仍然存在。

有沒有人有任何想法我可以克服這個問題?

+0

問題是Access,Excel和VBA – Dani 2012-03-20 11:18:06

+0

大聲笑,我還有什麼其他的選擇? – Bruder 2012-03-20 11:21:50

+0

LAMP,http://en.m.wikipedia.org/wiki/LAMP_(software_bundle) – Dani 2012-03-21 05:35:25

回答

1

你不提將由查詢所採取的實際時間,但這裏有幾個想法:

  1. 請確保您有索引數據庫中的所有,你是分組字段或過濾。

  2. 如果你是數據庫的唯一用戶,以獨佔方式打開它:
    對於ADO,使用連接字符串:

    "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFile & ";Mode=12;" 
    
  3. 使用DAO而不是ADO
    DAO原生Access,通常更快。

    第一件事是一個參考門禁引擎添加到Excel:

    • 從IDE,在工具>參考,下井名單,並檢查:
      Microsoft Office 12.0 Access database engine Object Library

    • 如果您有Access 2010,參考將是:
      Microsoft Office 14.0 Access database engine Object Library。使用舊版本的Access(2003和以前版本),改爲使用Jet引擎(僅限MDB文件),它將是:
      Microsoft DAO 3.6 Object Library

    然後使用下面的VBA代碼將數據加載到工作表:

Public Sub LoadFromDb() 
     Dim db As DAO.Database 
     Dim rs As DAO.Recordset 
     ' Open the database in Exclusive mode ' 
     Set db = DBEngine.OpenDatabase("C:\Users\MyName\Desktop\DataBase.accdb", True) 
     ' Open the recordset as a snapshot, it's faster than the default dbDynaset ' 
     Set rs = db.OpenRecordset("SELECT CUSTOMER, DATE, REVENUE " & _ 
       "FROM [SALES DB] WHERE REGION='REGION1'", dbOpenSnapshot) 
     ' Copy the recordset to the sheet ' 
     Worksheets(1).Cells(2, 1).CopyFromRecordset rs 
     rs.Close 
     db.Close 
     Set rs = Nothing 
     Set db = Nothing 
    End Sub 
  1. 如果大多是從Access導入數據到一個顯示它們透視,您可能會更好地通過Access本身中的數據透視表服務。

  2. 關於這個問題,你知道你可以拆分你的數據庫來共享後端數據,並使用免費的Access Runtime來允許你所有的用戶查看你的報告並使用他們機器上的數據進行遊戲嗎?

  3. 遷移到SQL Server或其它數據庫可能/可能無法在所有解決您的問題:

    • 如果SQL Server是在你的機器,這將需要更多或更少的儘可能多的資源來計算查詢就好像MS Access數據庫在你的機器上一樣。

    • 如果SQL Server位於遠程機器上,大部分時間將用於網絡數據傳輸。

    • 您的瓶頸可能不是數據庫,現在是將大量數據導入電子表格本身的時候了。您可以嘗試從Access本身執行查詢並查看需要多長時間。

  4. 如果你有那麼多的數據中進行篩選,Excel中可能是不適合這個職位的最佳工具,你可以通過一個專門的報告或商業智能應用程序得到更好的服務。
    有很多開源和商業平臺,比如:

+0

謝謝你的回覆。這真的是有幫助的東西。當你說問題不是查詢本身,而是實際上是excel中的inport時,你是對的。它在Access中運行得更快。我會嘗試像你所建議的那樣使用DAO,如果這也失敗了,也許我會遷移到Access。在那個說明中,Set en = CreateObject(「DAO.DBEngine」)產生一個錯誤_「activex組件不能創建對象」_。任何線索如何解決這個問題?另外,我看到你刪除了'rs.Open strSQL,cn,0,1 Worksheets(1).Cells(2,1).CopyFromRecordset rs'是這樣嗎?再次感謝你的幫助! – Bruder 2012-03-22 07:44:43

+0

實際上,我用'Set en = CreateObject(「DAO.DBEngine.36」)'解決了_「activex組件無法創建對象」的問題。現在我得到一個彈出窗口,要求輸入或瀏覽DSN。那是什麼?我該怎麼做?我很抱歉,我在這件事上真的很糟糕! – Bruder 2012-03-22 07:53:20

+1

@Bruder:我更新了一下代碼。關於DAO異常,請檢查此KB http://support.microsoft.com/kb/157471 – 2012-03-22 08:00:23

2

正如你猜測的那樣,數據庫不得不做更多的計算,主要是因爲你的GROUP BY。想想第二個查詢中必須發生的事情 - 數據庫需要查看所有約600k行,才能返回第一行,以防萬一最後一行發生最早的排序客戶。儘管當然,數據庫可以通過對客戶的索引來優化。但是,您還將MONTH和YEAR函數應用於字段並對其進行分組,因此數據庫需要在每行都做一些工作,然後才能夠計算出要返回的第一行。

您的第一個查詢幾乎可以立即開始返回數據,因爲它可以順序查看銷售數據庫表,並返回與該區域匹配的每一行。

由於您是在單臺桌面上執行此操作,所以實際的數據量可能不是決定整體花費多長時間的重要因素。 (稍後編輯)對不起,這可能會令人困惑。我的意思是,在數據庫和Excel電子表格之間移動的數據總量不是主要決定因素 - 移動600k和450k之間的差異不會那麼大。主要決定因素是數據庫必須做多少決策工作。但是,如果您通過網絡傳輸數據(例如從中央SQL Server數據庫)傳輸數據,那麼傳輸的數據量將成爲總體時間中的一個更大因素。

+0

謝謝你的回答理查德!由於數據量不是問題,所以我猜(就像Dani指出的那樣)我使用的軟件可能是。你知道還有什麼其他途徑可以讓這種任務更快嗎? – Bruder 2012-03-20 11:27:45

+0

您可能需要考慮轉移到sql server以獲得這些查詢的任何重大性能改進。或更多的內存(特別是如果你可以將整個數據庫存入內存)或使用SSD磁盤來存儲訪問數據庫。 – Richard 2012-03-20 11:47:13