ado recordset filter медленно...
У меня проблема: vc++ & удлаленный сервер mssql. Если на ado в recordset->filter в условие поставить несуществующее значение, то ответ от сервера приходит примерно через минуту.
Что можно сделать чтобы ускорить процесс?
Самый реальный выход для меня видится в том, чтобы не фильтровать recordset, а каждый раз открывать его с нужным условием. Но каждый раз коннектиться к удаленной базе новым recordset->open думаю будет очень долго, программа обрабатывает около 60к строк.
Заранее спасибо
мне много и не надо:)
у меня два. Один открывает 1ую таблицу, а второй ищет совпадения во 2ой таблице.
Думаете по времени не критично на удаленный сервер в цикле посылать select * from table2 where as='smth' ?
Может можно как-то это пограмотнее сделать...
Можно сделать чтобы АДО взял себе (к клиенту) все записи и поработал с ними?
может и локально... но у меня сетевые мониторы начинают гореть возле часиков. И ответа нет минуту если совпадение не найдено. Поэтому я и подумал что на сервере.
Может подскажете что надо сделать чтобы фильтр отвечал быстрее при несовпадении?
Вот фрагменты кода чтобы было понятно как я настраиваю соединение
pConn.CreateInstance(__uuidof(Connection));
rs.CreateInstance(__uuidof(Recordset));
rs_c.CreateInstance(__uuidof(Recordset));
pConn->Open(strCnn, _bstr_t(m_login), _bstr_t(m_password), adConnectUnspecified);
rs_c->Open(sql,_variant_t((IDispatch *)pConn), adOpenStatic, adLockOptimistic, adCmdText );
filtr = L"prefix="+s_prefix;
rs->Filter = filtr;
у меня два. Один открывает 1ую таблицу, а второй ищет совпадения во 2ой таблице.
Думаете по времени не критично на удаленный сервер в цикле посылать select * from table2 where as='smth' ?
Может можно как-то это пограмотнее сделать...
Можно сделать чтобы АДО взял себе (к клиенту) все записи и поработал с ними?
правильней будет посылать на сервер запрос
и таких запросов на одно подключение можно повесить сотни.
и таких запросов на одно подключение можно повесить сотни.
сотни сотнями.. но к сожалению скорость для нас очень важна. 7к записей обрабатываются 4 минуты. А 70к видимо будет минут сорок :(
Может mssql медленный? Или использовать не АДО, а ДАО или ОДБЦ. Или закидывать таблицы себе и обрабатывать у себя, а потом отсылать обратно.
Есть же какие нибудь методы!
Кстати
дало прирост с каждой тысячи запросов + 50 бонусных) Мелочь, а уже приятно
если я правильно понял выражение автора "удаленный сервер" то тут проблема не сколько в запросе, сколько в количестве пересылаемых данных и скорости канала.
Ты себе представляешь - как должен быть написан запрос, который возвращает 7К записей за 4 минуты? :) тут разве что он действительно через диалап работает :)
Ты себе представляешь - как должен быть написан запрос, который возвращает 7К записей за 4 минуты? :) тут разве что он действительно через диалап работает :)
да не вопрос: БД сотрудников с фотами, которые в БД хранятся, в нашей базе такая таблица (правда парадоксовская) весит ~ 800 мб. по локалке открывается минуты за 3-4 и там записей меньше ~ 4 тыс.
Там две таблицы: 6к и 40к записей.
Из первой таблицы берется строчка c id. Потом ищется совпадение во второй таблице. Если совпадения нет, то в id обрезается правая цифра и опять проверяется на совпадение. id очень длинные и поэтому на многие записи приходится по 3-7 запросов.
К тому же кроме первой таблицы в 6к записей есть еще такие таблицы для обработки от 3к до 10к записей.
Вот в чем дело.
А план запроса таков:
2. если нет совпадения при
valuefrom2table = select value from 2table where id=idfrom1table;
то из idfrom1table убирается правая цифра и второй шаг повторяется
3. update 1table set value=valuefrom2table;
6k записей обрабатываются за 4 минуты, а не результат возвращается через 4 минуты...
Надеюсь понятно.
И то о чем я писал раньше: recordset->filter у меня при несовпадении во втором шаге думает полминуты прежде чем дать отрицательный результат. Поэтому по совету охотник333 попробовал
2. формировать новый запрос
3. открывать рекордсет с новым запросом и смотреть результат.
Может фильтр бы работал быстрее, если бы работал...
Жду ваших идей по этому поводу. Заранее спасибо
"Может в консерватории что-то исправить?" (с) Жванецкий
Во первых - спросить у гугла что такое "план запроса"
во вторых - у него же выяснить что такое "нормализация БД" и "уникальный идинтификатор", "индекс БД", "внешние ключи"
в третьих - в свете полученной информации прочесть свое сообщение.
"Может в консерватории что-то исправить?" (с) Жванецкий
Во первых - спросить у гугла что такое "план запроса"
Могу только догадываться что такое план запроса. Написал так, чтобы Вы поняли, что это адресуется Вам.
Это поле я назвал id в форуме для простоты описания. А вообще это префикс.
А про нормализацию и индексацию почитаю. Спасибо
Нет. Я за план допроса.
Время выполнения кстати удалось сократить заменив поля text на nvarchar(50). Поиск идет быстрее. Так же проиндексировал одну таблицы сделав поле primary key. Внешний ключ мне не поможет... Буду тестировать отпишусь.
Просто иногда надо искать по двум полям, одно int primary key другое nvarchar.
Может есть еще какие-то пути индексации нескольких полей?
Просто иногда надо искать по двум полям, одно int primary key другое nvarchar.
Может есть еще какие-то пути индексации нескольких полей?
Если, прежде чем что либо делать, прочесть внимательно документацию, то легко можно обнаружить - на самом деле все делается.
У меня нет никакого желания пересказывать литературу по базовым принципам работы с БД - для этого используйте гугль. Вы судя по всему не нашли времени даже по диагонали прочесть найденный материал.
Добавление второго поля в первыичный ключ делается элементарно (пример для 2005)
DROP CONSTRAINT [PK__spr_object__7C8480AE]
GO
ALTER TABLE [dbo].[spr_object]
ADD PRIMARY KEY CLUSTERED ([object_id], [object_name])
WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY]
GO
это мало поможет, пока не приведешь базу к нормальному виду
Перенес код циклов в хранимые процедуры и привел таблицы к нормальному виду (искомые поля сделал примари кей). Оптимизировало с 40 минут до 50 сек :). А если без хранимой процедуры, то 10 мин. Так что хранимые процедуры все таки помогают.
Подскажите как запросами из программы на С++ создать хранимую процедуру? Мне надо динамически создавать процедуры, и потом запускать их. Если это возможно. Спасибо
Одно загадка - зачем создавать ХП каждый раз? Существенное ускорение вы получили за счет того, что план запроса ХП был создан при ее создании. При динамическом создании ИМХО врядли вы получите такой выиграш.
Так рекордсет и соединение же открывается на определенную базу... Может и не понадобится указывать базу...
Я правильно понял? ХП такого содержания
AS
Select * from table
GO
Можно создать и запустить на исполнение из программы на С++ такими строчками:
pConn->Execute('AS');
pConn->Execute('Select * from table');
pConn->Execute('GO');
pConn->Execute('test');
Просто в одной строчке типа такого
query = "CREATE PROCEDURE test
AS
Select * from table
GO";
Не присваивается почему то... Заранее спасибо
UPDATE
Вопрос отменяется. С "\n" получилось.