Форум программистов, компьютерный форум, киберфорум
Microsoft Access
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 26.04.2025
Сообщений: 7

Медленно выполняется удалённая выборка

31.05.2025, 16:36. Показов 1368. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Если кто может подскажите пожалуйста. Раньше была разделённая база Access, база (таблицы) висела в локальной папке и к ней локально были подключены интерфейсы с пользовательскими формами. Всё работало очень хорошо. Но со временем нужно было сделать удалённое подключение через VPN. Установил на сервер SQL Server 2022, экспортировал в него таблицы Access, с помощью ODBC Driver 18 for SQL Server и VBA установил связи базы с интерфейсов через туннель WireGuard. Все работает хорошо кроме одного. В базе имеется таблица, в ней 36000 записей. В интерфейсе есть поле например "Номер_удостоверения" Поиск нужной строки ведётся именно по этому полю. Включаю макрос "Найти запись" в окно ввожу например 0000456, данные находит за 3 секунды, а ввожу например 234765 данные программа ищет почти две минуты. Пробовал запрос штатный, писал на VBA, в SQL Server делал индексированное поле по которому ведётся поиск всё равно такая же ситуация. Одна мысль может VPN провайдеры прижимают или что то делаю не так. Хотя в самом SQL любая запись в таблице с помощью запроса появляется в секунды. Может что то подскажете
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
31.05.2025, 16:36
Ответы с готовыми решениями:

Почему в ARCHIVELOG так медленно выполняется DDL?
Здравствуйте, у меня проблема. Включаю режим ARCHIVELOG и Oracle начинает жутко тормозить при...

Медленно выполняется хранимая процедура
Процедура содержит в себе инструкцию Merge с переносом данных из одной тяжёлой таблицы в другую с...

Запрос на ASP выполняется медленно, чем на Management Studio
Привет народ! У меня на ASP странице есть запрос. SELECT DISTINCT dbo.Tumanlar.TumanNomi, ...

7
Эксперт MS Access
 Аватар для Eugene-LS
13172 / 5869 / 1504
Регистрация: 05.10.2016
Сообщений: 16,488
31.05.2025, 16:42
Цитата Сообщение от aleksandr76 Посмотреть сообщение
234765 данные программа ищет почти две минуты
Код поиска в студию!
А лучше всю форму + подключение к тестовой базе SQL Server.
0
0 / 0 / 0
Регистрация: 26.04.2025
Сообщений: 7
31.05.2025, 17:14  [ТС]
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
Private Sub cmdSearch_Click()
    Dim searchValue As String
    Dim searchField As String
    Dim ctrl As Control
    Dim rs As DAO.Recordset
    Dim resultMsg As Integer
    Dim recordCount As Integer
    Dim currentPosition As Integer
    Dim firstBookmark As Variant
    
    ' Определение активного поля для поиска
    Set ctrl = Screen.PreviousControl
    If ctrl Is Nothing Or Not (TypeOf ctrl Is TextBox Or TypeOf ctrl Is ComboBox) Then
        MsgBox "Выберите поле для поиска.", vbExclamation
        Exit Sub
    End If
    searchField = ctrl.Name
    
    ' Запрос значения для поиска
    searchValue = InputBox("Введите значение для поиска в поле " & searchField, "Поиск")
    If searchValue = "" Then Exit Sub
    
    ' Сохраняем текущую позицию
    firstBookmark = Me.Bookmark
    
    ' Составление SQL-запроса
    Dim sql As String
    sql = "SELECT * FROM Таблица_работников WHERE [" & searchField & "] LIKE '*" & Replace(searchValue, "'", "''") & "*'"
    
    ' Открытие Recordset с результатами
    Set rs = CurrentDb.OpenRecordset(sql, dbOpenSnapshot, dbReadOnly)
    
    ' Проверка наличия записей
    If rs.EOF Then
        MsgBox "Совпадений не найдено.", vbInformation
        Exit Sub
    End If
    
    ' Подсчет количества найденных записей
    rs.MoveLast
    recordCount = rs.RecordCount
    rs.MoveFirst
    
    ' Основная обработка
    currentPosition = 1
    Do Until rs.EOF
        ' Формируем условие поиска
        Dim searchCondition As String
        If IsNull(rs.Fields(searchField).Value) Then
            searchCondition = "[" & searchField & "] IS NULL"
        Else
            Select Case rs.Fields(searchField).Type
                Case dbText, dbMemo
                    searchCondition = "[" & searchField & "] = '" & Replace(rs.Fields(searchField).Value, "'", "''") & "'"
                Case dbDate
                    searchCondition = "[" & searchField & "] = #" & Format(rs.Fields(searchField).Value, "yyyy\/mm\/dd") & "#"
                Case Else
                    searchCondition = "[" & searchField & "] = " & rs.Fields(searchField).Value
            End Select
        End If
        
        ' Ищем запись в форме
        Me.RecordsetClone.FindFirst searchCondition
        If Not Me.RecordsetClone.NoMatch Then
            Me.Bookmark = Me.RecordsetClone.Bookmark
            Me.Refresh
            DoEvents
            
            ' Показываем запись пользователю
            resultMsg = MsgBox("Запись " & currentPosition & " из " & recordCount & vbCrLf & _
                             "Показать следующую запись?", vbYesNo + vbQuestion, "Просмотр записей")
            
            ' Прерывание, если пользователь решил прекратить просмотр
            If resultMsg <> vbYes Then Exit Do
        End If
        
        ' Переход к следующей записи
        rs.MoveNext
        currentPosition = currentPosition + 1
    Loop
    
    ' Сообщение, если закончились записи
    If rs.EOF And currentPosition > 1 Then
        MsgBox "Все записи просмотрены.", vbInformation
    ElseIf rs.EOF Then
        MsgBox "Совпадения не найдены в текущем наборе записей формы.", vbExclamation
        Me.Bookmark = firstBookmark ' Возвращаемся к исходной позиции
    End If
    
    ' Освобождаем ресурсы
    rs.Close
    Set rs = Nothing
End Sub
Добавлено через 12 минут
И ещё я заметил, когда поле не было индексировано то номер 000001 программа искала 2 минуты а номер 0000070 3 секунды, но когда я поле проиндексировал 000001 нашелся за 3 секунды но номера 0126287 ищутся почти 2 минуты.
0
Эксперт MS Access
 Аватар для Eugene-LS
13172 / 5869 / 1504
Регистрация: 05.10.2016
Сообщений: 16,488
31.05.2025, 17:39
Цитата Сообщение от aleksandr76 Посмотреть сообщение
Private Sub cmdSearch_Click()
Ух!!!!
... хм. вы прокачиваете по сети все данные таблицы пару раз точно.
Это очень негативно сказывается на скорости.

Цитата Сообщение от aleksandr76 Посмотреть сообщение
но когда я поле проиндексировал 000001 нашелся за 3 секунды но номера 0126287 ищутся почти 2 минуты
Это вопрос "удалённости" искомого от начала таблицы.

Используйте ADO, производя поиск на стороне сервера - будет шустро.
0
0 / 0 / 0
Регистрация: 26.04.2025
Сообщений: 7
31.05.2025, 17:51  [ТС]
Спасибо. Попробую
0
913 / 287 / 57
Регистрация: 01.06.2023
Сообщений: 812
01.06.2025, 10:27
И ещё я заметил, когда поле не было индексировано то номер 000001 программа искала 2 минуты а номер 0000070 3 секунды, но когда я поле проиндексировал 000001 нашелся за 3 секунды но номера 0126287 ищутся почти 2 минуты.
в вашем случае индекс и не поможет особо, из-за поиска в середине *...*.
Попробуйте поиск без начальной звездочки (если позволяет бизнес логика), это приведек к префиксному поиску и тогда индекс возможно задействовать
0
0 / 0 / 0
Регистрация: 26.04.2025
Сообщений: 7
01.06.2025, 15:13  [ТС]
Вот постарался по новому (напрямую подключиться, всё равно не то (5 записей ищет пять минут). То есть при первом запуске макроса через 3 секунды заполняются поля первыми данными первой записи и открывается сообщение что найдено 5 записей и вопрос "Показать следующую запись". Вот тут то и начинается интересное при нажатии на Да опять отправляется запрос поиска уже второй записи (как я понял по полю Код) и опять SQL начинает искать эту запись в таблице только по полю Код. Получается что разные запросы что бы получить пять значений я минимум раз шесть гоняю по интернету. Как бы сделать что бы один раз отправил запрос, SQL выбрал всё из таблицы и все данные отправил клиенту, тот только путём выбора выбрал нужную запись.
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
Private Sub Кнопка80_Click()
    On Error GoTo ErrorHandler
    
    Dim startTime As Double
    Dim executionTime As String
    startTime = Timer ' Засекаем время начала выполнения
    
    Dim searchValue As String
    Dim searchField As String
    Dim ctrl As Control
    Dim conn As ADODB.Connection
    Dim cmd As ADODB.Command
    Dim rs As ADODB.Recordset
    Dim resultMsg As VbMsgBoxResult
    Dim recordCount As Integer
    Dim currentPosition As Integer
    Dim firstBookmark As Variant
    Dim connString As String
    
    ' Логирование начала выполнения
    Debug.Print "[" & Now & "] Начало выполнения макроса"
    
    
    Set ctrl = Screen.PreviousControl
    If ctrl Is Nothing Then
        executionTime = Format((Timer - startTime) / 86400, "hh:mm:ss")
        MsgBox "Не выбрано поле для поиска. Сначала кликните в нужное поле." & vbCrLf & _
               "Время выполнения: " & executionTime, vbExclamation, "Ошибка"
        Debug.Print "Ошибка: не выбрано поле для поиска"
        Exit Sub
    End If
    
    If Not (TypeOf ctrl Is TextBox Or TypeOf ctrl Is ComboBox) Then
        executionTime = Format((Timer - startTime) / 86400, "hh:mm:ss")
        MsgBox "Поиск возможен только по полям TextBox или ComboBox" & vbCrLf & _
               "Время выполнения: " & executionTime, vbExclamation, "Ошибка"
        Debug.Print "Ошибка: выбрано поле неподдерживаемого типа: " & TypeName(ctrl)
        Exit Sub
    End If
    
    searchField = ctrl.Name
    Debug.Print "Поле для поиска: " & searchField
    
    '  Запрос значения для поиска
    searchValue = InputBox("Введите точное значение для поиска в поле " & searchField, "Поиск")
    If searchValue = "" Then
        executionTime = Format((Timer - startTime) / 86400, "hh:mm:ss")
        Debug.Print "Поиск отменен пользователем. Время выполнения: " & executionTime
        Exit Sub
    End If
    
    Debug.Print "Ищем значение: " & searchValue
    
    '  Сохраняем текущую позицию
    On Error Resume Next
    firstBookmark = Me.Bookmark
    If Err.Number <> 0 Then
        Debug.Print "Не удалось сохранить текущую позицию: " & Err.Description
        firstBookmark = Null
    End If
    On Error GoTo ErrorHandler
    
    '  Подключение к SQL Server
    connString = "Driver={ODBC Driver 18 for SQL Server};" & _
                 "Server=;" & _
                 "Database=;" & _
                 "Uid=;" & _
                 "Pwd=;" & _
                 "Encrypt=yes;TrustServerCertificate=yes;"
    
    Debug.Print "Пытаюсь подключиться к базе данных..."
    
    Set conn = New ADODB.Connection
    conn.connectionString = connString
    conn.Open
    
    If conn.State <> adStateOpen Then
        executionTime = Format((Timer - startTime) / 86400, "hh:mm:ss")
        MsgBox "Не удалось подключиться к базе данных" & vbCrLf & _
               "Время выполнения: " & executionTime, vbCritical, "Ошибка"
        Debug.Print "Ошибка подключения к базе данных"
        GoTo CleanUp
    End If
    
    Debug.Print "Подключение успешно установлено"
    
    ' Создание и выполнение команды
    Set cmd = New ADODB.Command
    With cmd
        .ActiveConnection = conn
        .CommandText = "SELECT * FROM База_сотрудников WHERE [" & searchField & "] = ?"
        .CommandType = adCmdText
        .Parameters.Append .CreateParameter("@searchValue", adVarWChar, adParamInput, Len(searchValue), searchValue)
    End With
    
    Debug.Print "Выполняю SQL запрос: " & cmd.CommandText
    
    Set rs = New ADODB.Recordset
    rs.CursorLocation = adUseClient
    rs.Open cmd, , adOpenStatic, adLockReadOnly
    
    '  Проверка результатов
    If rs.BOF And rs.EOF Then
        executionTime = Format((Timer - startTime) / 86400, "hh:mm:ss")
        MsgBox "Совпадений не найдено для значения: " & searchValue & vbCrLf & _
               "Время выполнения: " & executionTime, vbInformation, "Результат"
        Debug.Print "Записей не найдено"
        GoTo CleanUp
    End If
    
    '  Подсчет записей
    rs.MoveLast
    recordCount = rs.recordCount
    rs.MoveFirst
    
    Debug.Print "Найдено записей: " & recordCount
    
    ' Отображение результатов
    currentPosition = 1
    Do Until rs.EOF
        ' Формируем условие поиска
        Dim searchCondition As String
        Dim fieldValue As Variant
        
        fieldValue = rs.Fields("Код").Value ' Предполагаем, что есть поле Код
        
        Debug.Print "Обрабатываю запись Код: " & fieldValue & " (" & currentPosition & "/" & recordCount & ")"
        
        ' Ищем запись в форме по Код
        Me.RecordsetClone.FindFirst "[Код] = " & fieldValue
        If Me.RecordsetClone.NoMatch Then
            Debug.Print "Запись Код " & fieldValue & " не найдена в форме"
        Else
            Me.Bookmark = Me.RecordsetClone.Bookmark
            Me.Refresh
            DoEvents
            
            Debug.Print "Отображаю запись Код: " & fieldValue
            
            executionTime = Format((Timer - startTime) / 86400, "hh:mm:ss")
            resultMsg = MsgBox("Найдена запись " & currentPosition & " из " & recordCount & vbCrLf & _
                             "Показать следующую запись?" & vbCrLf & _
                             "Время выполнения: " & executionTime, _
                             vbQuestion + vbYesNo, "Результат поиска")
            
            If resultMsg = vbNo Then Exit Do
        End If
        
        currentPosition = currentPosition + 1
        rs.MoveNext
    Loop
    
    If currentPosition > recordCount Then
        executionTime = Format((Timer - startTime) / 86400, "hh:mm:ss")
        MsgBox "Просмотрено все " & recordCount & " записей" & vbCrLf & _
               "Время выполнения: " & executionTime, vbInformation, "Завершено"
        Debug.Print "Все записи просмотрены"
    End If
    
CleanUp:
    ' Закрытие соединений
    On Error Resume Next
    If Not rs Is Nothing Then
        If rs.State = adStateOpen Then rs.Close
        Set rs = Nothing
    End If
    
    If Not cmd Is Nothing Then Set cmd = Nothing
    
    If Not conn Is Nothing Then
        If conn.State = adStateOpen Then conn.Close
        Set conn = Nothing
    End If
    
    executionTime = Format((Timer - startTime) / 86400, "hh:mm:ss")
    Debug.Print "[" & Now & "] Завершение выполнения макроса. Общее время: " & executionTime
    Exit Sub
    
ErrorHandler:
    executionTime = Format((Timer - startTime) / 86400, "hh:mm:ss")
    MsgBox "Произошла ошибка:" & vbCrLf & _
           "Номер: " & Err.Number & vbCrLf & _
           "Описание: " & Err.Description & vbCrLf & _
           "Модуль: " & Err.Source & vbCrLf & _
           "Время выполнения: " & executionTime, vbCritical, "Ошибка"
    
    Debug.Print "ОШИБКА [" & Now & "]: " & Err.Number & " - " & Err.Description & " в " & Err.Source & _
                ". Время выполнения: " & executionTime
    
    Resume CleanUp
End Sub
Логи____________________________________ _________________________________
[01.06.2025 14:53:56] Начало выполнения макроса
Поле для поиска: Фамилия
Ищем значение: Иванов
Пытаюсь подключиться к базе данных...
Подключение успешно установлено
Выполняю SQL запрос: SELECT * FROM База_охотников WHERE [Фамилия] = ?
Найдено записей: 5
Обрабатываю запись Код: 41 (1/5)
Отображаю запись Код: 41
Обрабатываю запись Код: 8929 (2/5)
Отображаю запись Код: 8929
Обрабатываю запись Код: 20519 (3/5)
Отображаю запись Код: 20519
Обрабатываю запись Код: 25204 (4/5)
Отображаю запись Код: 25204
Обрабатываю запись Код: 32450 (5/5)
Отображаю запись Код: 32450
Все записи просмотрены
[01.06.2025 15:00:07] Завершение выполнения макроса. Общее время: 00:06:11

Может быть поле Код проиндексировать, а то 5 записей 6 минут - это много
0
Мы один, давай на "ты"
3849 / 1393 / 345
Регистрация: 16.06.2016
Сообщений: 3,288
01.06.2025, 16:11
aleksandr76, Создание запроса к серверу
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.06.2025, 16:11
Помогаю со студенческими работами здесь

Очень медленно работает выборка INNER JOIN
Добрый день! У меня есть таблица компании, таблица недвижимости и таблица с параметрами...

Выборка из таблици товаров по самому максимальному рейтингу магазина, рейтинг мазаницов если есть одиноковые, выборка уже по минимальной цене
Всем привет, нужна помошь. Имеется следующая таблица товаров Таблица: products её колонки...

Выборка уникальных записей с максимальными датами, и затем выборка по найденому
Как вообще такой запрос лучше составить? У меня есть таблица User(id) и Message( id,...

Выборка задолженностей по таблице (выборка строк с пустыми ячейкам даты оплаты) для отчета
Имеется таблица учета продаж, в ней нужно сделать выборку по дате оплаты для ежемесячного отчета....

Выборка данных из нескольких таблиц. Аналитическая выборка данных
16 Для каждого отдела выбрать отношение зарплаты и комиссионных сотрудников отдела к объему...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru