如何确定哪个表使用Access数据库中的最大空间

时间:2009-10-07 16:25:22

标签: ms-access

有没有简单的方法来确定Access 2007数据库中每个表使用多少空间?

我有一个非常大的Access数据库,需要找出哪个表占用的空间最多。行计数没有提供有关已用空间的足够信息。

此致

/弗兰克

6 个答案:

答案 0 :(得分:5)

这实际上是一个有趣的问题,因为Access使用可变长度记录来存储它的数据。

准确执行此操作的最佳方法是遍历表中的每个记录和每个字段,并累加字段的长度。如果表格很大,可能需要一段时间。由于索引和关系,它不会增加大小。

在我们的Total Access Analyzer程序中,我们有一些报告使用简单的记录大小估计值乘以记录数来估算表大小。此处显示了一个示例:http://fmsinc.com/MicrosoftAccess/Documentation/Reports/Table_SizeBySize.html

这可能足以进行球场估计或相对大小比较。

另一种可能非常准确的衡量方法是创建一个新数据库并将表导出到其中。压缩数据库并从中减去空白数据库大小以获取表的大小。

答案 1 :(得分:5)

我知道这是一篇旧帖子,但我根据自己对同一问题的经验提出了解决方案。我的解决方案是将所有表导出到文本文件。每个文本文件的大小大致与它在mdb / accdb文件中使用的空间成比例。

下面的代码将在当前数据库文件夹下创建一个子文件夹“ temp_table_size ”,并将所有表格导出到该文件夹​​。您可以传递一个参数来仅处理本地表。完成后,它会告诉您导出了多少个表,并询问您是否要打开该文件夹。按大小对该文件夹进行排序,您将很快识别出罪魁祸首。我使用这个例程来查找在部署之前我可能忘记清除的表,或者帮助我了解当我继承其他人的数据库时大表的位置。

为了使这个例程对我来说更方便,我将此代码添加到Access加载项,以便我可以针对任何数据库运行它。该加载项还具有导出所有其他Access对象的功能,因此我可以看到哪些表单/报表占用了数据库中的空间。如果有任何兴趣,也许我会找个地方分享它。

Public Sub DocDatabase_Table(Optional bolLocalTablesOnly As Boolean = False)
 '====================================================================
 ' Name:    DocDatabase_Table
 ' Purpose: Exports the tables in this database to a series of
 '          text files.  The size of each text file will give you
 '          an idea of what tables use the most disk space.
 '
 ' Author:  Ben Sacherich
 ' Date:    5/2/2011
 '====================================================================
    On Error GoTo ErrorHandler

    Dim dbs As Database ' or Variant if this fails.
    Dim td As TableDef
    Dim strSaveDir As String
    Dim lngObjectCount As Long
    Dim lngCount As Long
    Dim strMsg As String
    Dim varReturn As Variant

    Set dbs = CurrentDb() ' use CurrentDb() to refresh Collections

    ' Export to a subfolder of the current database folder.
    strSaveDir = CurrentProject.path & "\temp_table_size\"

    If Len(strSaveDir) > 0 Then

        strMsg = "This feature exports all of the tables in this database to a series of " _
            & "comma delimited text files.  The size of each text file will give you " _
            & "an idea of what tables use the most disk space." & vbCrLf & vbCrLf

        ' Get a count of the tables, minus the system tables.
        If bolLocalTablesOnly = True Then
            lngObjectCount = DCount("Name", "MSysObjects", "Type=1 AND Name not like 'MSys*' AND Name not like '~*'")
            strMsg = strMsg & "There are " & lngObjectCount & " local tables in this database. " _
                & vbCrLf & vbCrLf
        Else
            ' Include Local, Linked, and ODBC tables
            lngObjectCount = DCount("Name", "MSysObjects", "Type in (1,4,6) AND Name not like 'MSys*' AND Name not like '~*'")
            strMsg = strMsg & "There are " & lngObjectCount & " tables in this database " _
                & "(including local, linked, and ODBC)." & vbCrLf & vbCrLf
        End If
        strMsg = strMsg & "The tables will be exported to a subfolder of the current database:  " _
            & strSaveDir & vbCrLf & vbCrLf
        strMsg = strMsg & "Do you want to continue?"

        If MsgBox(strMsg, vbYesNo + vbInformation, "Export Tables") = vbYes Then

            If Dir(strSaveDir, vbDirectory) = "" Then
                MkDir strSaveDir
            End If

            ' Initialize and display message in status bar.
            varReturn = SysCmd(acSysCmdInitMeter, "(" & Format((lngCount) / lngObjectCount, "0%") & ")  Preparing tables", lngObjectCount)

            dbs.TableDefs.Refresh
            For Each td In dbs.TableDefs ' Tables
                If (bolLocalTablesOnly = True And Len(td.Connect) = 0) _
                  Or (bolLocalTablesOnly = False) Then

                    If Left(td.Name, 4) <> "MSys" And Left(td.Name, 1) <> "~" Then
                        Debug.Print td.Name, td.Attributes

                        ' Update message in status bar.
                        varReturn = SysCmd(acSysCmdSetStatus, "(" & Format((lngCount + 1) / lngObjectCount, "0%") _
                            & ")  Exporting table: " + td.Name)

                        DoCmd.TransferText acExportDelim, , td.Name, strSaveDir & "Table_" & td.Name & ".txt", True
                        lngCount = lngCount + 1

                    End If
                End If
            Next td

            'Remove the Progress Meter
            varReturn = SysCmd(acSysCmdRemoveMeter)

            If MsgBox("Exported " & lngCount & " object(s)." _
                & vbCrLf & vbCrLf & "Do you want to open the destination folder: " & strSaveDir & " ? " _
                , vbSystemModal + vbYesNo + vbInformation, "Table Size") = vbYes Then

                ' Open the output folder in Windows Explorer
                Call Shell("explorer.exe " & strSaveDir, vbNormalFocus)
            End If
        End If
    End If

Exit_Sub:
    Set td = Nothing
    Set dbs = Nothing

    Exit Sub

ErrorHandler:

    Debug.Print Err.Number, Err.Description
    Select Case Err
        Case "3011"
            MsgBox "Table '" & td.Name & "' could not be found or has a broken link." _
                & vbCrLf & vbCrLf & "Link: " & td.Connect _
                & vbCrLf & vbCrLf & "Click OK to continue.", vbExclamation, "Error 3011"
            Resume Next
        Case "75"
            ' This happens when you try to create a folder name that already exists.
            ' For this Q&D function, ignore the error.
            Resume Next
        Case Else
            MsgBox Err.Description
            Resume Next
    End Select

    GoTo Exit_Sub

End Sub

答案 2 :(得分:4)

对于正常运行的Access数据库,您可以获得简单的工具Access Memory Reporter 1.0,它显示表和索引所需的内存量。请注意,我自己没有尝试过这个工具。

一旦发现最大的桌子,你的目标是什么?你的MDB有多大?你最近压缩了吗?

压缩它会缩小多少?那就是你在其中创建和删除大量的表/记录?如果是这样,请参阅我的网站上的TempTables.MDB page,其中说明了如何在您的应用中使用临时MDB。

你在桌子上使用了很多图形吗?

答案 3 :(得分:1)

我正在使用Access 2003,很容易获得表记录计数。表记录计数表示表大小的大小。记录越多,尺寸越大。 如何获得表记录数?

  1. 通过Access 2003打开数据库,
  2. 点击“数据库工具”标签
  3. 点击“数据库文档管理工具”(可能是其他名称。)
  4. 点击“全部”,然后点击“确定”
  5. 您将看到一个新的白色地面页面显示所有表格的表信息。单击“TXT”(在Word图标下)
  6. 导出到txt
  7. 您将TXT保存到文件中。我们将它命名为tableinfor.txt
  8. 通过txt编辑器打开“tableinfo.txt”。搜索关键字“RecordCount”。 我想你知道哪张桌子占用的空间最多。

答案 4 :(得分:1)

您可以将每个表单独复制到单独的Access数据库,然后比较每个表的大小。虽然它不会为您提供表格本身的确切大小,但每个文件的大小大致显示每个表格的大小。

答案 5 :(得分:0)

这是我的方法: 1.收集数据库中的所有非系统表。 2.将每个表导出到临时数据库,然后比较之前和之后的大小。 3.显示包含收集的信息的表,然后删除临时数据库。

无论如何,这只是一个估计,因为由于关系,unicode压缩等原因很难精确计算大小。

将此Sub复制到全局模块并使用F5运行它:

Sub CheckTableSize()
    ' Table Size Analysis
    Dim DB As DAO.Database, NewDB As String, T As DAO.TableDef, SizeAft As Long, _
        SizeBef As Long, RST As DAO.Recordset, F As Boolean, RecCnt As Long

    Const StTable As String = "_Tables"

    Set DB = CurrentDb

    NewDB = Left(DB.Name, InStrRev(DB.Name, "\")) & Replace(Str(Now), ":", "-") & " " & _
        Mid(DB.Name, InStrRev(DB.Name, "\") + 1, Len(DB.Name))
    Application.DBEngine.CreateDatabase NewDB, DB_LANG_GENERAL

    F = False
    For Each T In DB.TableDefs
        If T.Name = StTable Then
            F = True: Exit For
        End If
    Next T
    If F Then
        DB.Execute "DELETE FROM " & StTable, dbFailOnError
    Else
        DB.Execute "CREATE TABLE " & StTable & _
            " (tblName TEXT(255), tblRecords LONG, tblSize LONG);", dbFailOnError
    End If

    For Each T In DB.TableDefs
        ' Exclude system tables:
        If Not T.Name Like "MSys*" And T.Name <> StTable Then
            RecCnt = T.RecordCount
            ' If it's linked table:
            If RecCnt = -1 Then RecCnt = DCount("*", T.Name)
            If RecCnt > 0 Then DB.Execute "INSERT INTO " & StTable & _
                " (tblName, tblRecords) " & _
                "VALUES ('" & T.Name & "', " & RecCnt & ")", dbFailOnError
        End If
    Next T

    Set RST = DB.OpenRecordset("SELECT * FROM " & StTable, dbOpenDynaset)
    If RST.RecordCount > 0 Then
        Do Until RST.EOF
            Debug.Print "Processing table " & RST("tblName") & "..."
            SizeBef = FileLen(NewDB)
            DB.Execute ("SELECT * " & _
            "INTO " & RST("tblName") & " IN '" & NewDB & "' " & _
            "FROM " & RST("tblName")), dbFailOnError
            SizeAft = FileLen(NewDB) - SizeBef
            RST.Edit
                RST("tblSize") = SizeAft
            RST.Update
            Debug.Print "    size = " & SizeAft
            RST.MoveNext
        Loop
    Else
        Debug.Print "No tables found!"
    End If
    RST.Close: Set RST = Nothing

    Debug.Print ">>> Done! <<<"
    MsgBox "Done!", vbInformation + vbSystemModal, "CheckTableSize"
    Kill NewDB
    Set DB = Nothing

    DoCmd.OpenTable StTable, acViewNormal, acReadOnly
End Sub

from my github repository