2010-06-07 3 views
4

VBA에서 내 Access 2003 데이터베이스에 많은 레코드 (이상한 파일 형식의 파일)를 삽입하려면 아래 코드를 실행하려고합니다. 많은 실험을 거친 후,이 코드는 내가 얻은 것 중 가장 빠릅니다. 즉, 내 컴퓨터에서 약 15 초 만에 10000 개의 레코드를 수행합니다. 적어도 14.5 초 (즉, 거의 모든 시간)가 UpdateBatch에 대한 단일 호출에 포함됩니다.MS Access : ADODB.Recordset.BatchUpdate가 Application.ImportXML보다 훨씬 느린 이유는 무엇입니까?

JET 엔진이 UpdateBatch를 지원하지 않는다고 읽었습니다. 어쩌면 더 나은 방법이있을 수 있습니다.

지금은 JET 엔진이 아주 느린 것 같지만 그럴 수는 없습니다. 아래 코드로 'testy'테이블을 생성 한 후 마우스 오른쪽 버튼을 클릭하고 내보내기를 선택하여 XML로 저장했습니다. 그런 다음 마우스 오른쪽 버튼을 클릭하고 가져 오기를 선택한 다음 XML을 다시로드했습니다. 총 XML 파일 가져 오기 시간? 1 초 미만, 즉 최소 15 배 이상 빠릅니다.

확실히 임시 파일을 쓰지 않아도되는 Access에 데이터를 삽입하는 효율적인 방법이 있습니까?

Sub TestBatchUpdate() 
    CurrentDb.Execute "create table testy (x int, y int)" 

    Dim rs As New ADODB.Recordset 
    rs.CursorLocation = adUseServer 
    rs.Open "testy", CurrentProject.AccessConnection, _ 
     adOpenStatic, adLockBatchOptimistic, adCmdTableDirect 

    Dim n, v 
    n = Array(0, 1) 
    v = Array(50, 55) 

    Debug.Print "starting loop", Time 
    For i = 1 To 10000 
     rs.AddNew n, v 
    Next i 
    Debug.Print "done loop", Time 

    rs.UpdateBatch 
    Debug.Print "done update", Time 

    CurrentDb.Execute "drop table testy" 
End Sub 

빠른 삽입을 할 수있는 API가 있다면 C/C++에 의지 할 의향이 있습니다. 그러나 나는 그것을 찾을 수없는 것 같습니다. Application.ImportXML이 문서화되지 않은 API를 사용하고있는 것은 아닙니다.

+0

또한이 쿼리는 말괄량없이 빠르게 실행됩니다. "testy select testy select top 10000 * testy". 1 초도 남지 않았습니다. 그래서 분명히 10000 개의 행을 삽입하는 것은 JET가 많은 문제를 안고있는 것이 아닙니다. – apenwarr

답변

2

ADO로이 작업을 수행해야하는 경우가 아니면 DAO를 대신 사용하십시오. 당신의 절차 및 DAO 버전을 가진 나의 휴대용 퍼스널 컴퓨터에 시간은 여기있다 :

ADO: 
starting loop 9:51:59 PM 
done loop  9:52:00 PM 
done update 9:52:54 PM 

DAO: 
starting loop 9:58:29 PM 
done loop  9:58:31 PM 
done update 9:58:31 PM 

이것은 나가 사용한 DAO 버전이다.

Sub TestBatchUpdateDAO() 

    CurrentDb.Execute "create table testy (x int, y int)" 

    Dim rs As DAO.Recordset 
    Set rs = CurrentDb.OpenRecordset("testy", dbOpenTable, dbAppendOnly) 
    Dim i As Long 

    Debug.Print "starting loop", Time 
    For i = 1 To 10000 
     rs.AddNew 
     rs!x = 50 
     rs!y = 55 
     rs.Update 
    Next i 
    Debug.Print "done loop", Time 

    'rs.UpdateBatch ' 
    Debug.Print "done update", Time 

    rs.Close 
    Set rs = Nothing 
    CurrentDb.Execute "drop table testy" 
End Sub 
+0

신성한 암소, 나는 그것을 믿을 수 없다! 네가 옳아! 나는 * 모든 것을 시도했다고 생각했지만 * 나는 이것을 잊었다! BTW, "삽입 할 ..."쿼리 (한 행에 하나) DAO 함께 슈퍼 천천히 있지만 방법은 실제로 엄청나게 빠릅니다. 감사! – apenwarr

+0

또 다른 참고 사항 : 위의 방법은 COM 마샬링으로 인해 C 프로그램과 같은 다른 프로세스에서 MSACCESS.EXE 프로세스와 통신하는 경우 속도가 느려지지만 MSACCESS.EXE 프로세스 내부에서 실행중인 경우 빠릅니다. VBA에 액세스). CreateObject ("DAO.DBEngine.36")를 사용하면 느려질 수 있습니다. 현재 프로세스 내에 DAO 인스턴스를 만들고 마샬링을 피하는 OpenDatabase(). 그 차이는 약 30 배속입니다! C 프로그램에서 이는 초당 800 회의 인서트/초와 24,000 회의 인서트/초를 의미합니다. – apenwarr

관련 문제