re: вы "переместили вычисления на внутренний сервер SQL"
Полагаю, вы имеете в виду, что вы перенесли данные на внутренний сервер. Это не означает, что вычисления происходят там или происходят быстрее.
Фактически, это более вероятно, увеличит время вычислений, потому что вычисления все еще выполняются на любой машине, выполняющей запрос (я полагаю, ваш интерфейс, если вы не выполнили какое-то сложное кодирование для выполнения хранимых процедур SQL) и т. д., на бэкэнде, и извлекаем ваши данные оттуда).
... Так что теперь это все тот же компьютер , который выполняет вычисления, как и раньше, - но теперь данные должны передаваться с сервера на локальный компьютер каждый раз, когда вы выполнить запрос, в отличие от ранее, когда данные уже были локальными.
Общие виновные
Без просмотра вашей базы данных никто не может сделать намного больше, чем догадаться, и я предполагаю, что у вас есть несколько плохо спроектированных запросов, заполняющих каждую из этих форм, которые открываются.
... возможно различные воплощения одного и того же запроса , работающего снова и снова? Например, общая проблема в моем опыте: существует ли комбинированный список, в котором перечислены имена сотрудников или другие данные, ограниченные по различным критериям? Возможно, аналогичные запросы должны быть выполнены для каждой формы? Возможно несколько запросов для каждой из нескольких форм?
Дублированная рабочая нагрузка должна быть упорядочена, и то, как это сделать, зависит от вашей ситуации. В приведенном выше примере статическая таблица может создаваться каждый раз при изменении списка сотрудников, который включает только имена, которые должны быть включены в поля со списком. Эта таблица может храниться локально и, таким образом, может заменить несколько повторяющихся запросов, которые рассчитываются несколько раз при открытии каждой базы данных.
Другая распространенная ошибка - использование в запросе трудоемких пользовательских функций, которые должны запускать эту функцию для тысяч записей. Функция, выполнение которой занимает четверть секунды, может стать реальной проблемой, когда она вызывается 10000 раз одним запросом.
Время каждого шага
Несколько грязный, но эффективный способ определить, какой процесс (ы) вносят большую часть задержки, - это ввести и «перетекать» ваш код вызовами процедуры, которая будет записывать, сколько времени занимает выполнение каждого процесса. (Я только что прошел через это, что привело к значительному сокращению времени, необходимого для обработки «огромных» файлов.)
Ниже приведена процедура, которую я привел в пример. Сколько или как мало вы хотите регистрировать, зависит от вашей ситуации (и как быстро вы диагностируете проблему).
Имейте в виду, что это предназначено для временного использования , поскольку собирается добавить дополнительное время обработки (хотя и не так, как ваши существующие процессы, по звукам это!)
Пример реализации
Когда вы открываете базу данных, возможно, происходит несколько вещей. Возможно, у вас есть макрос AutoExec
, который запускает процедуру, которая открывает формы и выполняет запросы, которые вызывают функции и т. Д.
Цель здесь - выяснить, сколько времени занимает каждый из этих шагов. Вид плохого примера, но, надеюсь, это имеет смысл:
Sub YourOnOpenProcedure()
'<-- add our logging sub here
SomeProcessYouCall_1
'<-- add our logging sub here
SomeProcessYouCall_1
'<-- add our logging sub here
SomeFormYouOpen
'<-- add our logging sub here
SomethingElseYouDo
'<-- add our logging sub here (no 'EventName')
End Sub
Function SomeFunctionCalledByYourQuery() As Integer
'<-- add our logging sub here
SomeFunctionCalledByYourQuery = 1 + 2
End Function
Процедура-время процедуры
Добавьте эту процедуру и переменные или что-то похожее на публичный модуль:
Option Compare Database
Option Explicit ' <-- Always, especially when troubleshooting!
Public startTime As Single, prevEventName As String
Sub timeIt(eventName As String)
'call this sub with the name of an event/process/sub/form/etc you're about to run
'prints time of previous event, and prepare for the next one if specified
'specify an empty string ("") after the end of the last event to return the last runtime.
If startTime <> 0 Then 'log the duration of the last event
'log the previous event
Debug.Print "-> " & prevEventName & ":", Round(Timer - startTime, 1) & " seconds"
'optional: log "event' in a local table (needs table, see notes)
'DoCmd.SetWarnings False 'supress record-append confirmation
'DoCmd.RunSQL "insert into tblLog select '" & prevEventName & "' as eName, " & Timer - startTime & " as eRunTime"
'DoCmd.SetWarnings True
startTime = 0
prevEventName = ""
End If
If eventName <> "" Then
startTime = Timer 'prepare for the next event
prevEventName = eventName
End If
End Sub
Регистрация данных в таблице является необязательной (см. Ниже для настройки таблицы) и зависит от вашей ситуации, например, масштаб этой проблемы. Как, он сообщит в Немедленном Окне ( Ctrl + G из VBA, чтобы открыть).
лично я всегда предпочитаю «больше данных», и несколько минут дополнительной работы могут значительно упростить определение процессов, вызывающих беспокойство.
Пример использования:
Если мы представим, что процессы, которые вы запускаете, это MsgBox
:
Sub DemoProcedure()
timeIt "msgbox1:Hi"
MsgBox "hi"
timeIt "msgbox2:Hello"
MsgBox "hello"
timeIt "msg3:Heya"
MsgBox "heya"
timeIt "msg4:Hola"
MsgBox "hola"
timeIt "" '<-- call with empty string to get the last time
End Sub
Пример вывода:
Это приводит к выводу в Immediate Window что-то вроде:
-> msgbox1:Hi: 1.2 seconds
-> msgbox2:Hello: 1.1 seconds
-> msg3:Heya: 222.7 seconds
-> msg4:Hola: 0.4 seconds
Понятно, что моя msg "heya" процедура здесь проблема.:)
Запись в таблицу
Чтобы записать данные о синхронизации в локальную таблицу (а также в окно «Немедленное окно»), откомментируйте три соответствующие строки в кодеи добавьте в таблицу что-то вроде этого:
![img](https://i.stack.imgur.com/Ley4h.png)
Он будет регистрировать данные, что-то вроде:
![img](https://i.stack.imgur.com/cE3Rd.png)
Советыдля повышения производительности базы данных Access
- Использование Сжатие и восстановление
- Загрузка только что вам нужно
- Убедитесь, что во всех ваших таблицах есть первичные ключи
- Оптимизация путем добавления вторичных индексов
- Разделение базы данных
Дополнительная информация об этом из источника .
... есть множество других статей в Интернете с советами по улучшению Accessпроизводительность.
Суть в том, что вряд ли это будет единственная проблема."Целое здоровье базы данных", включая ультраорганизацию снизу вверх, жизненно важно.В тех же случаях соотношение затрат и выгод может даже оправдать начало и перепроектирование «идеальной» базы данных, начиная с чертежной доски (буквально!) ...
Удачи!