Конференция "Базы" » Out of memory в результате фетча большого числа записей. [D7, FB 2.1]
 
  • Дмитрий Белькевич (02.07.09 14:57) [0]
    Записей около 3-х млн. Можно ли что-то придумать, кроме рекомендации меньше фетчить? Все записи в памяти не нужны, нужна только одна, текущая запись.
    Компоненты - IBX
  • Дмитрий Белькевич (02.07.09 14:57) [1]
    3 млн селектов тоже не предлагать ;) Базе и так тяжело...
  • Sergey13 © (02.07.09 15:03) [2]
    > [0] Дмитрий Белькевич   (02.07.09 14:57)
    > нужна только одна, текущая запись.

    А что значит текущая запись, если она еще не на клиенте?
  • DrPass © (02.07.09 15:29) [3]

    > Можно ли что-то придумать

    Можно. Unidirectional:= true
  • Дмитрий Белькевич (02.07.09 15:42) [4]

    > А что значит текущая запись, если она еще не на клиенте?


    Которую клиент себе уже забрал и с ней может работать.
  • Дмитрий Белькевич (02.07.09 15:43) [5]

    > Можно. Unidirectional:= true


    Спасибо, посмотрю.
  • Anatoly Podgoretsky © (02.07.09 15:52) [6]
    Не смотреть, а делать.
  • Sergey13 © (02.07.09 15:58) [7]
    > [4] Дмитрий Белькевич   (02.07.09 15:42)

    Я что то не въезжаю.
    Запрашиваем в запросе все записи из трехмиллионной таблицы. Сколько то уже закачалось на клиента. Пользователь решает, что полуторамиллионная запись - это, в принципе то, что ему надо. Так что ли? Или ему надо взять любую запись?
  • DrPass © (02.07.09 16:22) [8]

    > Sergey13 ©   (02.07.09 15:58) [7]

    Там, вообще-то, про пользователя ни слова не было сказано :)
  • PEAKTOP © (02.07.09 16:54) [9]
    > Записей около 3-х млн. Можно ли что-то придумать, кроме
    > рекомендации меньше фетчить? Все записи в памяти не нужны,
    >  нужна только одна, текущая запись.


    А описать задачу нельзя ?
    Чего-то совсем я не пойму, зачем вообще понадобилось все 3 млн фетчить. Поиск что-ли ?
  • Sergey13 © (02.07.09 16:55) [10]
    > [8] DrPass ©   (02.07.09 16:22)

    Замена пользователя на клиента ничего для меня лично не прояснила. Ну да ладно.
  • DrPass © (02.07.09 17:03) [11]

    > Sergey13 ©   (02.07.09 16:55) [10]
    > Замена пользователя на клиента ничего для меня лично не
    > прояснила. Ну да ладно.

    Пользователь - это живой человек. Клиент - это в общем случае бездушная программа. Которая может выгребать 3 млн записей для того, чтобы закачать в другую СУБД, сделать статистический анализ или нарисовать по ним кардиограмму.
  • stas © (02.07.09 17:20) [12]
    >Дмитрий Белькевич   (02.07.09 14:57) [1]
    Уменьшить количество полей в селекте.
  • Дмитрий Белькевич (02.07.09 18:10) [13]
    >Я что то не въезжаю.

    Как уже народ сказал, пользователь - не живой. Есть программный цикл, который последовательно выбирает записи и обрабатывает информацию. Ему в единицу времени нужна только одна запись.

    >Поиск что-ли ?

    Можно сказать и так. В базе - линки на файлы. Поиск недостающих и излишних.

    >Уменьшить количество полей в селекте.

    Это временно поможет, но не решит проблему. 6 млн (или 10) опять будут валить программу. Тем не менее, я уже выбираю достаточный минимум полей.
  • PEAKTOP © (02.07.09 18:36) [14]
    А дергать записи пакетами по 100 000 штук нельзя ?

    Из спецификации оператора SELECT:

    SELECT
       [DISTINCT | ALL]
       [FIRST {<record_number> | (:param_recordnumber) } [SKIP <record_number> | (:param_recordnumber) ] ]
    .....
    [ORDER BY <sort_value_list>    ]
    ..........

  • Дмитрий Белькевич (02.07.09 18:51) [15]

    > А дергать записи пакетами по 100 000 штук нельзя ?


    Я не уверен, есть ли гарантии, что не пропустится какая-то одна (а часто бывает, что именно одна-две из миллиона и нужны). Так как в базу частенько пишут (добавляют/удаляют) другие потоки. Хотя это не очень критично и есть надежда, что в пределах одной транзакции каша не должна возникнуть. Хотелось бы, конечно, одним селектом ограничится, но если иначе - никак, то буду что-то с несколькими селектами думать.

    Посмотрел Unidirectional. Похоже на то, что нужно, по крайней мере, на кэширование записей влияет точно. Попробую.
  • Игорь Шевченко © (03.07.09 02:46) [16]
    У меня не вышло, в свое время (два года назад) - надо было выбрать из большой таблицы данные (хоть по одной записи) в результате одного select.
    Как раз из Firebird, вытащить надо было много миллионов записей.

    Я пробовал и BDE, и IBX и ADO и dbExpress, которые unidirectional по сути.
    В результате выбирал многими select-ами, благо организация данных позволяла.
  • Sergey13 © (03.07.09 08:48) [17]
    > [15] Дмитрий Белькевич   (02.07.09 18:51)
    > Я не уверен, есть ли гарантии, что не пропустится какая-то одна

    ИМХО, если выбирать по диапазону ID-шников, то вряд ли пропустится что-либо
    where id>=:Par1 and id<:Par2
  • Дмитрий Белькевич (11.08.09 12:54) [18]

    > Я пробовал и BDE, и IBX и ADO и dbExpress, которые unidirectional
    > по сути.


    Мда... Малообещающе.

    Продолжаю воевать с ibx'ами. Замечены некоторые закономерности.

    С выключенным unidirectional память 'течёт' всегда.

    С включенным unidirectional память 'течёт' только в одном случае - если доступаемся к полям блоб. Если к char, integer, просто пустой цикл - то количество занимаемой памяти не меняется.

    Опять баги VCL? Или просто особенности? Буду разбираться дальше...
  • turbouser © (11.08.09 13:03) [19]

    > Дмитрий Белькевич   (11.08.09 12:54) [18]
    >
    >

    Как насчет компонентов UIB ? http://www.progdigy.com/?page_id=5
  • Игорь Шевченко © (11.08.09 13:26) [20]
    Вот, кстати, ветка с моими поисками решения

    http://delphimaster.net/view.php?folder=18&file=1-1160361442
  • Anatoly Podgoretsky © (11.08.09 13:41) [21]
    Кстати по сути одноправленен только dbexpress, остальные многовекторны.

    По проблеме, можно еще повозиться с сервными курсорами.
  • Дмитрий Белькевич (11.08.09 14:13) [22]
    Пока не ясно, где именно датасет отжирает память, что бы знать, куда дальше двигаться. Где-то же он это делает.

    IBAlloc вызывается только при старте запроса.

    В модуле IBCustomDataSet GetMem/SetLength вызывается несколько раз при старте запроса и больше не дёргается.

    В TDataSet FBuffers тоже вроде бы никто не трогает.

    Никто случаем не знает, где данные хранятся, которые отжирают память?

    Замечено еще одно. UniDirectional есть непосредственно в TIBCustomDataSet и в предке, TDataSet - FIsUniDirectional. Так вот. В самом TIBCustomDataSet UniDirectional действительно устанавливается в True, в предке же FIsUniDirectional остаётся False.
  • Дмитрий Белькевич (11.08.09 14:19) [23]

    > Как насчет компонентов UIB ? http://www.progdigy.com/?page_id=5


    Под 2009-й вроде бы не работают. По крайней мере, их почему-то в поставке jedi нету.


    > Кстати по сути одноправленен только dbexpress, остальные
    > многовекторны.


    Может быть в самом деле dbexpress'овские компоненты попробовать...
  • MsGuns © (11.08.09 14:34) [24]
    Все-таки так и не понял какого лешего это "переливание" выполнять на клиенте. Или при обработке могут возникать ситуации, требующие вмешательство человека ?
  • Дмитрий Белькевич (11.08.09 14:38) [25]

    > Все-таки так и не понял какого лешего это "переливание"
    > выполнять на клиенте. Или при обработке могут возникать
    > ситуации, требующие вмешательство человека ?


    Объясняю. В таблице лежат линки на файлы (и еще некоторая информация). Файлы расположены локально (или на присоединённых шарах). Нужно пробежаться по всем записям, и у несуществующих файлов, но имеющихся в базе, проставить пометки (в отдельном поле), что их нет.
  • Игорь Шевченко © (11.08.09 14:39) [26]

    > Может быть в самом деле dbexpress'овские компоненты попробовать.
    > ..


    Мне помогли, об чем в ветке из [20] и написано, пост № 45
  • Ega23 © (12.08.09 07:18) [27]

    > Файлы расположены локально (или на присоединённых шарах).


    Локально на сервере или на клиенте?
  • Виталий Панасенко (12.08.09 09:41) [28]
    А сами IBX обновлялись?
  • Виталий Панасенко (12.08.09 09:49) [29]
    И еще: а если использовать TIBSQL, вместо TIBDataSet?
  • Дмитрий Белькевич (02.10.09 18:26) [30]
    Возвращаясь...

    >Локально на сервере или на клиенте?

    Локально на сервере, или на расшаренных папках в сети.

    >А сами IBX обновлялись?

    Да.

    >TIBSQL

    И как же мне в нём все записи перебрать? Делать миллионы запросов?

    >dbexpress'овские

    Неудобны тем, что еще одну дллку таскать нужно. Стараюсь количество файлов в проекте держать минимально возможножным.

    Пока остановился на UIB. Всё отлично работает, только под 2009 пока UIB'а нет в поставке JEDI...
  • turbouser © (02.10.09 20:30) [31]

    > Дмитрий Белькевич   (02.10.09 18:26) [30]


    > ока остановился на UIB. Всё отлично работает, только под
    > 2009 пока UIB'а нет в поставке JEDI...

    Есть отдельно:
    http://rapidshare.com/files/172766840/UIB20081212.rar
  • turbouser © (02.10.09 20:31) [32]

    > turbouser ©   (02.10.09 20:30) [31]

    + или тут :)
    http://rapidshare.com/files/171425897/UIB.rar

  • > Дмитрий Белькевич   (02.10.09 18:26) [30]


    > >TIBSQL
    >
    > И как же мне в нём все записи перебрать? Делать миллионы
    > запросов?

    ты гонишь! ОДИН!!!! точно такой же как у TIBdataSet!
  • Дмитрий Белькевич (05.10.09 11:50) [34]
    >И еще: а если использовать TIBSQL, вместо TIBDataSet?

    Посмотрел. И что бы ви таки думали? Таки да :) Eof есть, Next есть. Попробовал - всё работает... Спасибо, опять всё переписывать :)

    Я-то почему-то думал, что у IBSQL eof/next нету...
  • Виталий Панасенко (05.10.09 12:07) [35]
    Таки пожалуйста...:-)
 
Конференция "Базы" » Out of memory в результате фетча большого числа записей. [D7, FB 2.1]
Есть новые Нет новых   [134435   +33][b:0][p:0.001]