有没有简单的方法来确定Access 2007数据库中每个表使用多少空间?
我有一个非常大的Access数据库,需要找出哪个表占用的空间最多。行计数没有提供有关已用空间的足够信息。
此致
/弗兰克
答案 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,很容易获得表记录计数。表记录计数表示表大小的大小。记录越多,尺寸越大。 如何获得表记录数?
答案 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