Как определить, какая таблица использует наибольшее пространство в базе данных Access

Есть ли какой-либо простой способ определить, сколько пространства используется в каждой таблице в базе данных Access 2007?

У меня необычно большая база данных Access, и вам нужно выяснить, какая таблица использует наибольшее пространство. Количество строк не дает достаточной информации об используемом пространстве.

Привет

/Франк

Ответ 1

Для функционирования баз данных доступа вы можете получить простой инструмент Access Memory Reporter 1.0, который показывает объем памяти, который нужны таблицам и индексам. Обратите внимание, что я сам не пробовал этот инструмент.

Какова ваша цель, когда вы обнаружите самую большую таблицу? Насколько велик ваш MDB? Вы недавно уплотнили его?

Сколько он сжимается, когда вы его сжимаете? То есть вы создаете и удаляете в нем много таблиц/записей? Если это так, посмотрите на странице TempTables.MDB на моем веб-сайте, который иллюстрирует использование временного MDB в вашем приложении.

Используете ли вы много графики в таблицах?

Ответ 2

На самом деле это интересная проблема, потому что Access использует записи переменной длины для хранения данных.

Лучший способ сделать это точно - это просмотреть каждую запись и каждое поле таблицы и сложить длину полей. Это может занять некоторое время, если таблицы большие. Это не поднимет размер из-за индексов и отношений.

В нашей программе Total Access Analyzer у нас есть несколько отчетов, которые предоставляют оценку размера таблицы, используя простую оценку размера записи, умноженную на количество записей. Пример показан здесь: http://fmsinc.com/MicrosoftAccess/Documentation/Reports/Table_SizeBySize.html

Этого может быть достаточно для приблизительных оценок или сравнительных сравнений размеров.

Другой, и, вероятно, очень точный способ измерить это - создать новую базу данных и экспортировать в нее таблицу. Сожмите базу данных и вычтите из нее пустой размер базы данных, чтобы получить размер таблицы.

Ответ 3

Я знаю, что это старый пост, но у меня есть решение, основанное на моем собственном опыте с тем же вопросом. Мое решение - экспортировать все таблицы в текстовые файлы. Размер каждого текстового файла примерно пропорционален тому, сколько места он использует в файле 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

Ответ 4

Я использую Access 2003, легко получить счетчик записей в таблице. Счетчик записей таблицы означает размер таблицы. Чем больше записей, тем больше размер. Как получить счет записи таблицы?

  • Откройте базу данных Access 2003,
  • Нажмите вкладку "Инструменты базы данных"
  • Нажмите "Инструмент управления документами базы данных" (может быть другое имя.)
  • Нажмите "Все" и "ОК"
  • Вы увидите новую белую наземную страницу, отображающую информацию о таблице для всей таблицы. Экспортируйте в txt, нажав кнопку "TXT" (значок "Значок" ).
  • Вы сохраните TXT в файл. Назовите его tableinfor.txt
  • Откройте "tableinfo.txt" в редакторе txt. ключевые слова поиска "RecordCount". Я думаю, вы знаете, какая таблица занимает больше всего места.

Ответ 5

Вы можете копировать каждую таблицу отдельно для разделения баз данных доступа, а затем сравнивать размер каждого из них. Хотя это не даст вам точный размер самих таблиц, размер каждого файла будет примерно равным размеру каждой таблицы.

Ответ 6

Вот мой подход: 1. Соберите все несистемные таблицы в базе данных. 2. Экспортируйте каждую таблицу во временную базу данных и сравните размер до и после. 3. Покажите таблицу с собранной информацией и удалите временную базу данных.

В любом случае, это только оценка, потому что трудно точно рассчитать размер из-за отношений, сжатия юникода и т.д.

Скопируйте этот 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 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

из моего репозитория github