ADO + mdb = низкая(?) скорость выборки

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

ADO + mdb = низкая(?) скорость выборки

Сообщение SergT » 03.06.2010 (Чт) 13:03

Доброе Время суток Всем!
Такая вот беда:

БД - Access 2003. К ней подключаемся из VB6:

Вот кусок кода:
Код: Выделить всё
Public CN As New ADODB.Connection
...
СN.CursorLocation = adUseClient
CN.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & PT & _
    ";Persist Security Info=False;Jet OLEDB:Database Password='12345'"
...
В модальной форме несколько раз подряд вызывается из модуля FIND_FIO:

Function FIND_FIO()

   Dim rst As New ADODB.Recordset
   Dim s$

   s = "SELECT ID,GR From TB1 Where UCase(Фамилия)='ИВАНОВ' And UCase(Имя)='ИВАН'" & _
   " And UCase(Отчество)='ИВАНОВИЧ'"

   rst.Open s, CN, adOpenForwardOnly, adLockReadOnly
s = ""
   If rst.RecordCount <> 0 Then
      Do While Not rst.EOF
      s = s & "Иванов Иван Иванович - " & _
       rst!GR &  " [Код = " & rst!ID & "]" & vbCrLf
          rst.MoveNext
          Loop
FIND_FIO = s

   If rst.State = adStateOpen Then rst.Close
   Set rst = Nothing
End function

Первый раз rst открывается с большой задержкой (~4 сек), затем моментально.
В чем причина первой задержки?
ID и GR - индексированные поля, при этом ID не допускает повторов.

Что я делаю неверно? Почему это происходит?
Заранее благодарю за любую помощь!
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение iGrok » 03.06.2010 (Чт) 13:21

А нафига нужен индекс на ID, GR, если ты выбираешь записи по другим полям?
На Ф.И.О. индексы есть?
label:
cli
jmp label

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение SergT » 03.06.2010 (Чт) 17:02

На ФИО индексов нет, а на остальные нужны для более быстрой выборки в других случаях. Но разве в этом проблема?
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение VVitafresh » 03.06.2010 (Чт) 17:21

SergT писал(а):Но разве в этом проблема?

Вполне вероятно, т.к. по этому полю идет поиск. Первый раз идет сканирование таблицы, при этом она кэшируется в памяти, поэтому последующие вызовы выполняются быстро.

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

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение iGrok » 03.06.2010 (Чт) 17:40

Каждый раз идёт выборка по одним и тем же значениям, или они всё-таки меняются?
label:
cli
jmp label

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение SLIM » 03.06.2010 (Чт) 20:15

iGrok писал(а):На Ф.И.О. индексы есть?

Не советую ставить индекс на текстовые поля такого (возможного) размера.
Пишите жизнь на чистовик.....переписать не удастся.....

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение VVitafresh » 03.06.2010 (Чт) 21:22

SLIM писал(а):
iGrok писал(а):На Ф.И.О. индексы есть?

Не советую ставить индекс на текстовые поля такого (возможного) размера.

Почему?
Если по этому полю необходим (частый) поиск, индекс просто необходим.
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение iGrok » 03.06.2010 (Чт) 21:54

SLIM писал(а):
iGrok писал(а):На Ф.И.О. индексы есть?

Не советую ставить индекс на текстовые поля такого (возможного) размера.

+1. Почему??? 0_o
label:
cli
jmp label

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение SergT » 03.06.2010 (Чт) 23:36

VVitafresh писал(а):Легко проверить построением индекса по полю и сравнением быстродействия.

Поставил индексы на ФИО - Ситуация не поменялась.
Хочу уточнить, что выборка осуществляется из модальной формы. Т.е. оператор заполняет поля и после каждого изменения - проверка. Первая проверка - тормоза, остальные - все быстро. Стоит закрыть-открыть форму, все сначала! Ощущение, что БД "запоминает" запрос и "забывает".
Код проверяю, но пока ничего не нашел. Однако ситуация повторяется и в других случаях. Раньше такого не замечал. Что делать? :( :shock:

ЗЫ:
Спасибо всем за участие. Прошу прощения за запоздалые ответы. Есть другие проблемы.
Тема для меня очень актуальна!
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение SLIM » 03.06.2010 (Чт) 23:41

Скорость работы с такими индексами упадет. Индекс хранится должен особым упорядоченным образом. Представьте как упорядочить текст не просто. И вот если в такую таблицу добавлять имена, то СУБД придется решать задачу куда это поместить, сравнив две строки. А строки сравниваются посимвольно. Куда проще сравнивать число.
Да и вообще, это противоречит нормализации БД. Хранить нужно ID Фамилии, и искать уже совпадения в отдельной таблице, а не в исходной.
Пишите жизнь на чистовик.....переписать не удастся.....

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение SergT » 03.06.2010 (Чт) 23:42

iGrok писал(а):Каждый раз идёт выборка по одним и тем же значениям, или они всё-таки меняются?

Нет конечно. Значения разные. Необходимо проверить совпадение ФИО в БД. Код несколько изменен, но даже в таком виде - ситуация такая же!
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение iGrok » 03.06.2010 (Чт) 23:58

А БД большая? Не оптимальнее ли будет её полностью закинуть в память, и дальше искать по рекордсету?
Просто аксесс сам по себе тормозной..

А повторные запросы(которые не тормозят) - с теми же фио, или с другими?
label:
cli
jmp label

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение SLIM » 04.06.2010 (Пт) 0:14

iGrok писал(а):А БД большая? Не оптимальнее ли будет её полностью закинуть в память, и дальше искать по рекордсету?
Просто аксесс сам по себе тормозной..

Разницы не будет на мой взгляд. Разница видна только если ты просто открываешь таблицу с тем, как ты используешь ее пр помощи ADO.

Правда, что мешает заиметь таблицу с ID-ками фамилий?
Пишите жизнь на чистовик.....переписать не удастся.....

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение SergT » 04.06.2010 (Пт) 0:30

БД не очень большая, около 20 000-30 000 записей. Вот полей в этой таблице 52. Это конечно нагрузка, но ведь я выбираю только 5.
Может быть где то в другом месте искать, курсоры и.т.д.? Может быть настройки БД какие-то неверные? Вообще-то настройки Access-ной БД влияют на подключение через ADO?
Подключение к БД идет по локальной сети. Может тут что-то? Хотя запросы по индексированным полям проходят быстро! :(
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение SergT » 04.06.2010 (Пт) 0:49

SLIM писал(а):Да и вообще, это противоречит нормализации БД. Хранить нужно ID Фамилии, и искать уже совпадения в отдельной таблице, а не в исходной.

Мне необходимо сравнить Фамилию, Имя и Отчество. Т.е. найти всех полных тёзок. ID у каждой ФИО есть. Вопрос несколько в другом. Если я удаляю все индексы из таблицы, то поиск по ID (он чаще) испытывает аналогичные проблемы. Почему вообще такое происходит? Скорость выборки то маленькая, то моментальная. Может быть где то ошибка в коде (ранее). Программа достаточно большая. Рекордсеты я внимательно закрываю после каждой процедуры. Может быть дело в настройках БД? Вообще - на что это похоже? Где копать?

Ниже была тема:
Использовании функции find Объекта RecordSet где:
alibek писал(а):
Откуда искать и в каком направлении — задается аргументами метода. Поэтому одного Find достаточно.

Может это прикрутить? Но мне нужны все тёзки.
Завтра попробую.
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение iGrok » 04.06.2010 (Пт) 2:33

Похоже это всё-таки на то, что у тебя бд в сети.
Попробуй выбирать в отдельный рекордсет ВЕСЬ набор ID + GR + F + I + O без условий.
Хранить этот рекордсет в памяти, и искать однофамильцев делая rst.Filter("ф = .. AND и = .. AND о = ...")
Будет долгая первая загрузка, но быстрый поиск потом. Ну и памяти жрать будет больше.

База же в сети. У тебя по сути идёт открытие базы по сети, скачивание индекса (для ID он маленький), и далее вытаскивание записи по индексу.
А если поиск не по индексу, или по большому индексу (в случае в Ф, И, О) - то качается вся бд и перебираются записи.
При последующих поисках всё это, видимо, успевает закешироваться..

Впрочем, DBA из меня тот ещё, и механизмы работы акцесса я себе не очень чётко представляю.
Так что может это всё и бред чистой воды. :roll:
label:
cli
jmp label

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение SLIM » 04.06.2010 (Пт) 6:29

может лучше предварительно отбирать пять полей в другую таблицу и по ней искать? Или попробовать вложенный запрос.
Пишите жизнь на чистовик.....переписать не удастся.....

HandKot
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 283
Зарегистрирован: 28.06.2006 (Ср) 13:34
Откуда: Sergiev Posad

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение HandKot » 04.06.2010 (Пт) 7:27

если нужно ТОЛЬКО найти однофамильцев,
то можно указать в св-вах конекшена вместо adUseClient
adUseServer, что, по идее, должно повысить скорость

не увевер, но можно так же запрос сохранить в самой базе и дергать его, а не создавать каждый раз.
I Have Nine Lives You Have One Only
THINK!

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение SergT » 04.06.2010 (Пт) 9:03

Попробую "поиграть" с индексами. Удалить все и затем добавлять по необходимости. Смущает только, что если БД лежит локально, то подобных глюков не наблюдалось. А вот при переносе БД на сервер ...
Попробую полазить по БД в поисках мусорных индексов. Однажды с другим проектом были сложности, так я создал новую БД и импотировал все таблицы. Глюки исчезли. Видимо что-то было. Кстати, а связи (ключи) могут влиять на скорость? Я вообще раньше представлял mdb как контейнер с данными. Оказалось - все гораздо сложнее. :shock:
Если не поможет, действительно придется разбивать таблицу на несколько и связывать их по ID.
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение VVitafresh » 04.06.2010 (Пт) 10:58

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

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение Andrey Fedorov » 30.07.2010 (Пт) 0:21

SergT писал(а):В модальной форме несколько раз подряд вызывается из модуля FIND_FIO:

Код: Выделить всё
Function FIND_FIO()
    ...
    s = "SELECT ID,GR From TB1 Where UCase(Фамилия)='ИВАНОВ' And UCase(Имя)='ИВАН'" & _
   " And UCase(Отчество)='ИВАНОВИЧ'"
   ...
End function

Первый раз rst открывается с большой задержкой (~4 сек), затем моментально.
В чем причина первой задержки?


Я бы задался вопросом = как оно у тебя вообще может работать? Ведь использовать VB-функции из запроса нельзя - это не Access. Программа просто обязана ругнуться.
Достаточно писать так:

Код: Выделить всё
    s = "SELECT ID,GR From TB1 Where Фамилия='ИВАНОВ' And Имя='ИВАН' And Отчество='ИВАНОВИЧ'"


Ну и я бы подумал над тем что будет если юзер введет в поле апостроф...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение FireFenix » 30.07.2010 (Пт) 1:11

Andrey Fedorov писал(а):Я бы задался вопросом = как оно у тебя вообще может работать? Ведь использовать VB-функции из запроса нельзя - это не Access

Тролололо....

UCASE() стандартная функа SQL для конвертации в верхний регистр
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение Andrey Fedorov » 30.07.2010 (Пт) 2:10

FireFenix писал(а):
Andrey Fedorov писал(а):Я бы задался вопросом = как оно у тебя вообще может работать? Ведь использовать VB-функции из запроса нельзя - это не Access

Тролололо....

UCASE() стандартная функа SQL для конвертации в верхний регистр


1. В данном контексте это функция на SQL, а Access.
2. Функции работают только если запрос выполняется из среды Access.
3. Приводить к верхнему регистру нафиг не нужно.
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

arvitaly
Постоялец
Постоялец
 
Сообщения: 485
Зарегистрирован: 12.04.2009 (Вс) 0:30
Откуда: Казань

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение arvitaly » 31.07.2010 (Сб) 2:04

1. В данном контексте это функция на SQL, а Access.
2. Функции работают только если запрос выполняется из среды Access.
3. Приводить к верхнему регистру нафиг не нужно.


1. :D
2. :D
3. :D

Такие громкие утверждения требуют доказательств

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение alibek » 31.07.2010 (Сб) 9:11

Последнее — это норма для БД.
Lasciate ogni speranza, voi ch'entrate.

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение Andrey Fedorov » 31.07.2010 (Сб) 19:21

arvitaly писал(а):Такие громкие утверждения требуют доказательств


А попробовать сложно?
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

arvitaly
Постоялец
Постоялец
 
Сообщения: 485
Зарегистрирован: 12.04.2009 (Вс) 0:30
Откуда: Казань

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение arvitaly » 31.07.2010 (Сб) 20:29

Что именно

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение iGrok » 31.07.2010 (Сб) 20:44

Andrey Fedorov писал(а):А попробовать сложно?

Ну я попробовал, дальше-то что? Сам бы попробовал, что ли..
UCASE() в запросе к акцессовской базе замечательно работает из VB6 через ADO.

Соответственно, прав ты только в третьем утверждении. Остальные два несколько далеки от истины.
label:
cli
jmp label

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение Andrey Fedorov » 31.07.2010 (Сб) 22:40

iGrok писал(а):Соответственно, прав ты только в третьем утверждении. Остальные два несколько далеки от истины.


Действительно - попробовал сам - функции с MDB-шками действительно работают:

Dim cn As New ADODB.Connection, r As New ADODB.Recordset

cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Program Files (x86)\Microsoft Visual Studio\VB98\BIBLIO.MDB;Persist Security Info=False"
cn.CursorLocation = adUseClient
cn.Open

r.Open "SELECT UCase(Author)+ ' >> ' + CStr(DateAdd(""m"", 2, now)) FROM Authors WHERE Left(Author,4) = 'Adam'", cn, adOpenStatic, adLockReadOnly
Debug.Print
Debug.Print
Do Until r.EOF
Debug.Print r(0)
r.MoveNext
Loop


Я почему-то был уверен в обратном...
Хотя в основном работаю с SQL-сервером...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: ADO + mdb = низкая(?) скорость выборки

Сообщение alibek » 31.07.2010 (Сб) 22:48

Andrey Fedorov писал(а):Действительно - попробовал сам - функции с MDB-шками действительно работают:

Дело не в MDB, а в Jet-провайдере. В документации об этом сказано, перечислены функции, которые поддерживаются.
LEN, TRIM, UCASE, LCASE и другие.
Lasciate ogni speranza, voi ch'entrate.

След.

Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 153

    TopList