Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

ado recordset filter медленно...

5.4K
20 октября 2009 года
cursor
114 / / 05.01.2008
Здравствуйте.
У меня проблема: vc++ & удлаленный сервер mssql. Если на ado в recordset->filter в условие поставить несуществующее значение, то ответ от сервера приходит примерно через минуту.
Что можно сделать чтобы ускорить процесс?
Самый реальный выход для меня видится в том, чтобы не фильтровать recordset, а каждый раз открывать его с нужным условием. Но каждый раз коннектиться к удаленной базе новым recordset->open думаю будет очень долго, программа обрабатывает около 60к строк.
Заранее спасибо
11
20 октября 2009 года
oxotnik333
2.9K / / 03.08.2007
коннект открыт один (при старте открывается и при завершении обрывается), а на него можно навешивать весьма много рекордсетов.
1
20 октября 2009 года
kot_
7.3K / / 20.01.2000
Разве фильтрация на рекордсете не локально выполняется? На сколько мне известно - локально.
5.4K
20 октября 2009 года
cursor
114 / / 05.01.2008
Цитата: oxotnik333
коннект открыт один (при старте открывается и при завершении обрывается), а на него можно навешивать весьма много рекордсетов.



мне много и не надо:)
у меня два. Один открывает 1ую таблицу, а второй ищет совпадения во 2ой таблице.
Думаете по времени не критично на удаленный сервер в цикле посылать select * from table2 where as='smth' ?
Может можно как-то это пограмотнее сделать...
Можно сделать чтобы АДО взял себе (к клиенту) все записи и поработал с ними?

5.4K
20 октября 2009 года
cursor
114 / / 05.01.2008
Цитата: kot_
Разве фильтрация на рекордсете не локально выполняется? На сколько мне известно - локально.



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

 
Код:
strCnn = L"Server="+m_ip+"; DRIVER=SQL SERVER; Persist Security Info=False;Database=PRFXMNG;User ID="+m_login+";Password="+m_password+";  ReadOnly=0;";
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;
11
20 октября 2009 года
oxotnik333
2.9K / / 03.08.2007
Цитата: cursor
мне много и не надо:)
у меня два. Один открывает 1ую таблицу, а второй ищет совпадения во 2ой таблице.
Думаете по времени не критично на удаленный сервер в цикле посылать select * from table2 where as='smth' ?
Может можно как-то это пограмотнее сделать...
Можно сделать чтобы АДО взял себе (к клиенту) все записи и поработал с ними?


правильней будет посылать на сервер запрос

 
Код:
select [только нужные поля] from table2 where as='smth'

и таких запросов на одно подключение можно повесить сотни.
5.4K
20 октября 2009 года
cursor
114 / / 05.01.2008
Цитата: oxotnik333
правильней будет посылать на сервер запрос
 
Код:
select [только нужные поля] from table2 where as='smth'

и таких запросов на одно подключение можно повесить сотни.


сотни сотнями.. но к сожалению скорость для нас очень важна. 7к записей обрабатываются 4 минуты. А 70к видимо будет минут сорок :(
Может mssql медленный? Или использовать не АДО, а ДАО или ОДБЦ. Или закидывать таблицы себе и обрабатывать у себя, а потом отсылать обратно.
Есть же какие нибудь методы!

Кстати

Цитата: oxotnik333
правильней будет посылать на сервер запрос
 
Код:
select [только нужные поля] from table2 where as='smth'


дало прирост с каждой тысячи запросов + 50 бонусных) Мелочь, а уже приятно

1
20 октября 2009 года
kot_
7.3K / / 20.01.2000
Для начала надо смотреть план запроса. И используемые им индексы - 7к записей - 4 минуты (!!!) это архимедленно. либо индексы не используются либо их нет вообще.
11
20 октября 2009 года
oxotnik333
2.9K / / 03.08.2007
Цитата: kot_
Для начала надо смотреть план запроса. И используемые им индексы - 7к записей - 4 минуты (!!!) это архимедленно. либо индексы не используются либо их нет вообще.


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

1
20 октября 2009 года
kot_
7.3K / / 20.01.2000
не думаю. разве что он на диалапе пытается данные получать. :)
Ты себе представляешь - как должен быть написан запрос, который возвращает 7К записей за 4 минуты? :) тут разве что он действительно через диалап работает :)
11
20 октября 2009 года
oxotnik333
2.9K / / 03.08.2007
Цитата: kot_
не думаю. разве что он на диалапе пытается данные получать. :)
Ты себе представляешь - как должен быть написан запрос, который возвращает 7К записей за 4 минуты? :) тут разве что он действительно через диалап работает :)


да не вопрос: БД сотрудников с фотами, которые в БД хранятся, в нашей базе такая таблица (правда парадоксовская) весит ~ 800 мб. по локалке открывается минуты за 3-4 и там записей меньше ~ 4 тыс.

5.4K
21 октября 2009 года
cursor
114 / / 05.01.2008
Канал - локальная сеть.
Там две таблицы: 6к и 40к записей.
Из первой таблицы берется строчка c id. Потом ищется совпадение во второй таблице. Если совпадения нет, то в id обрезается правая цифра и опять проверяется на совпадение. id очень длинные и поэтому на многие записи приходится по 3-7 запросов.
К тому же кроме первой таблицы в 6к записей есть еще такие таблицы для обработки от 3к до 10к записей.
Вот в чем дело.
А план запроса таков:

 
Код:
1. idfrom1table = select id from 1table; (6к записей)
2. если нет совпадения при
valuefrom2table = select value from 2table where id=idfrom1table;
то из  idfrom1table убирается правая цифра и второй шаг повторяется
3. update 1table set value=valuefrom2table;


6k записей обрабатываются за 4 минуты, а не результат возвращается через 4 минуты...
Надеюсь понятно.
И то о чем я писал раньше: recordset->filter у меня при несовпадении во втором шаге думает полминуты прежде чем дать отрицательный результат. Поэтому по совету охотник333 попробовал
 
Код:
1. закрывать рекордсет
2. формировать новый запрос
3. открывать рекордсет с новым запросом и смотреть результат.

Может фильтр бы работал быстрее, если бы работал...
Жду ваших идей по этому поводу. Заранее спасибо
1
21 октября 2009 года
kot_
7.3K / / 20.01.2000
мда.
"Может в консерватории что-то исправить?" (с) Жванецкий
Во первых - спросить у гугла что такое "план запроса"
во вторых - у него же выяснить что такое "нормализация БД" и "уникальный идинтификатор", "индекс БД", "внешние ключи"
в третьих - в свете полученной информации прочесть свое сообщение.
5.4K
21 октября 2009 года
cursor
114 / / 05.01.2008
Цитата: kot_
мда.
"Может в консерватории что-то исправить?" (с) Жванецкий
Во первых - спросить у гугла что такое "план запроса"


Могу только догадываться что такое план запроса. Написал так, чтобы Вы поняли, что это адресуется Вам.

Цитата: kot_
во вторых - у него же выяснить что такое "нормализация БД" и "уникальный идинтификатор", "индекс БД", "внешние ключи"


Это поле я назвал id в форуме для простоты описания. А вообще это префикс.
А про нормализацию и индексацию почитаю. Спасибо

5.4K
21 октября 2009 года
cursor
114 / / 05.01.2008
Осознал был неправ
1
21 октября 2009 года
kot_
7.3K / / 20.01.2000
Т.е. причины по которым запрос выполняется медленно и что нужно сделать понятны - либо требует дополнительных пояснений?
5.4K
21 октября 2009 года
cursor
114 / / 05.01.2008
Цитата: kot_
Т.е. причины по которым запрос выполняется медленно и что нужно сделать понятны - либо требует дополнительных пояснений?



Нет. Я за план допроса.
Время выполнения кстати удалось сократить заменив поля text на nvarchar(50). Поиск идет быстрее. Так же проиндексировал одну таблицы сделав поле primary key. Внешний ключ мне не поможет... Буду тестировать отпишусь.

5.4K
21 октября 2009 года
cursor
114 / / 05.01.2008
А что если мне надо бы пару полей в таблице primary key? mssql не позволяет создать.
Просто иногда надо искать по двум полям, одно int primary key другое nvarchar.
Может есть еще какие-то пути индексации нескольких полей?
1
21 октября 2009 года
kot_
7.3K / / 20.01.2000
ну с погреба как говорится виднее. насколько понятно по описанию - здесь стандартная задача использования foreign key
1
21 октября 2009 года
kot_
7.3K / / 20.01.2000
Цитата: cursor
А что если мне надо бы пару полей в таблице primary key? mssql не позволяет создать.
Просто иногда надо искать по двум полям, одно int primary key другое nvarchar.
Может есть еще какие-то пути индексации нескольких полей?


Если, прежде чем что либо делать, прочесть внимательно документацию, то легко можно обнаружить - на самом деле все делается.
У меня нет никакого желания пересказывать литературу по базовым принципам работы с БД - для этого используйте гугль. Вы судя по всему не нашли времени даже по диагонали прочесть найденный материал.
Добавление второго поля в первыичный ключ делается элементарно (пример для 2005)

Код:
ALTER TABLE [dbo].[spr_object]
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
5.4K
22 октября 2009 года
cursor
114 / / 05.01.2008
я догадывался, что существуют хранимые процедуры!
11
22 октября 2009 года
oxotnik333
2.9K / / 03.08.2007
Цитата: cursor
я догадывался, что существуют хранимые процедуры!


это мало поможет, пока не приведешь базу к нормальному виду

5.4K
25 октября 2009 года
cursor
114 / / 05.01.2008
Цитата: oxotnik333
это мало поможет, пока не приведешь базу к нормальному виду


Перенес код циклов в хранимые процедуры и привел таблицы к нормальному виду (искомые поля сделал примари кей). Оптимизировало с 40 минут до 50 сек :). А если без хранимой процедуры, то 10 мин. Так что хранимые процедуры все таки помогают.
Подскажите как запросами из программы на С++ создать хранимую процедуру? Мне надо динамически создавать процедуры, и потом запускать их. Если это возможно. Спасибо

1
25 октября 2009 года
kot_
7.3K / / 20.01.2000
Ну так приводили же уже код в паралельной ветке? Тот самый который начинается (как это не странно с "CREATE PROCEDURE"). только при том надо указать еще и базу в которой это все будет делаться.
Одно загадка - зачем создавать ХП каждый раз? Существенное ускорение вы получили за счет того, что план запроса ХП был создан при ее создании. При динамическом создании ИМХО врядли вы получите такой выиграш.
5.4K
26 октября 2009 года
cursor
114 / / 05.01.2008
Цитата: kot_
Тот самый который начинается (как это не странно с "CREATE PROCEDURE"). только при том надо указать еще и базу в которой это все будет делаться.


Так рекордсет и соединение же открывается на определенную базу... Может и не понадобится указывать базу...
Я правильно понял? ХП такого содержания

 
Код:
CREATE PROCEDURE test
AS
Select * from table
GO

Можно создать и запустить на исполнение из программы на С++ такими строчками:
 
Код:
pConn->Execute('CREATE PROCEDURE test');
pConn->Execute('AS');
pConn->Execute('Select * from table');
pConn->Execute('GO');
pConn->Execute('test');

Просто в одной строчке типа такого
 
Код:
CString query;
query = "CREATE PROCEDURE test
AS
Select * from table
GO";

Не присваивается почему то... Заранее спасибо

UPDATE
Вопрос отменяется. С "\n" получилось.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог