IRowsetFastLoad::InsertRow наоборот
От: .alex Ниоткуда  
Дата: 14.04.20 20:01
Оценка:
День добрый.
Использую IRowsetFastLoad::InsertRow для вставки данных в MSSQL, все работает на ура — миллионы строк в секунду...
Вопрос собственно в том можно ли сделать подобное наоборот, т.е. выкачать из БД кусками с такой же скоростью (ну или подобной) кучу данных? Обычный ADO на 1М строк (500 солбцов) затыкается...
Re: IRowsetFastLoad::InsertRow наоборот
От: BlackEric http://black-eric.lj.ru
Дата: 15.04.20 07:41
Оценка:
Здравствуйте, .alex, Вы писали:

A>День добрый.

A>Использую IRowsetFastLoad::InsertRow для вставки данных в MSSQL, все работает на ура — миллионы строк в секунду...
A>Вопрос собственно в том можно ли сделать подобное наоборот, т.е. выкачать из БД кусками с такой же скоростью (ну или подобной) кучу данных? Обычный ADO на 1М строк (500 солбцов) затыкается...

Работает реально быстро Techniques to bulk copy, import and export in SQL Server. Через что не разбирался, но думаю что через bcp.
https://github.com/BlackEric001
Re[2]: IRowsetFastLoad::InsertRow наоборот
От: .alex Ниоткуда  
Дата: 15.04.20 11:31
Оценка:
Здравствуйте, BlackEric, Вы писали:
BE>Работает реально быстро Techniques to bulk copy, import and export in SQL Server. Через что не разбирался, но думаю что через bcp.

Мне бы код... Видно, что "тулзы" это делают, а как не понятно...
Вот например, у меня если таблица в mssql сервере 1М строк и 500 столбцов... Management studio запрос: select * from tbl делает из нее минуты 3...
А если я делаю подобное из своей программы:
    _RecordsetPtr prsResult = NULL;

    if (!m_pConnection || (m_pConnection->State & adStateOpen) != adStateOpen) return prsResult;

    try
    {
        HRESULT hr = prsResult.CreateInstance(__uuidof(Recordset));
        prsResult->CursorType = adOpenStatic;
        prsResult->CursorLocation = adUseClient;
        prsResult->LockType = adLockReadOnly;
        prsResult->Open((_bstr_t)"select * from tbl", (IDispatch*)m_pConnection, adOpenStatic, adLockReadOnly, adCmdText);
    }
    catch (_com_error& e)
    {
        ...
        prsResult = NULL;
    }
    catch (...)
    {
        ...
        prsResult = NULL;
    }

    return prsResult; // return obtained RecordSet

Все встает колом на prsResult->Open()...
Как выгрузить в программу большой рекордсет? Может можно как-то по частям это делать?

UPD: в принципе разобрался, как сделать чтобы не "вставало колом") нужно поставить серверный курсор... Но все же может есть способ быстрее выгражать, чем через ADO?
Отредактировано 15.04.2020 12:53 .alex . Предыдущая версия .
Re[3]: IRowsetFastLoad::InsertRow наоборот
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 15.04.20 16:58
Оценка:
Здравствуйте, .alex, Вы писали:

A>Здравствуйте, BlackEric, Вы писали:

BE>>Работает реально быстро Techniques to bulk copy, import and export in SQL Server. Через что не разбирался, но думаю что через bcp.

A>UPD: в принципе разобрался, как сделать чтобы не "вставало колом") нужно поставить серверный курсор... Но все же может есть способ быстрее выгражать, чем через ADO?


Напрямую тащить из OLEDB провайдера?

Серверный Forward-Only курсор.

Биндишься к колонкам с указанием их родного типа. Для избежания преобразования данных.

И вперед.

Если провайдер поддерживает асинхронную загрузку, можно ёще и её включить. Но, по-моему, они (в MS) её не асилили.

---
Я тут лет 10 назад писал одну, ADODB-совместимую хреновину, которая получает множество через OpenRowset и позволяет фетчить данные из этого множества.

  Код выглядит как-то так
option explicit

dim cn
set cn=createobject("ADODB.Connection")

cn.Provider="MSOLEDBSQL"

cn.Properties("Data Source").value="HOME4"
cn.Properties("Integrated Security").value="SSPI"

call cn.Open()

call cn.BeginTrans()

call cn.Execute("USE TEST")

dim cursor
set cursor=createobject("LCPI.IBP.Samples.RowCursor")

set cursor.ActiveConnection=cn

cursor.Source="master"

call cursor.Open()

dim i

while(cursor.Fetch())
 wscript.echo "fetch record!"
 
 for i=0 to cursor.fields.count-1
  wscript.echo cursor(i).Name&"="&cursor(i).Value
 next

 wscript.echo "-----------"
wend

call cn.CommitTrans()

call cn.Close()

Я там заморачивался с оптимизацией и вроде даже получилось вытаскивать данные немного быстрее чем ADODB.

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

Если интересно, то эта хреновина (с исходными текстами и откомпилированном виде) есть в дистрибутиве IBProvider.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.