powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / substring BLOBа медленно
45 сообщений из 45, показаны все 2 страниц
substring BLOBа медленно
    #39922621
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В процедуру загружаю (через BLOB) достаточно большой текст (XML).
в процедуре произвожу "резку" текста по тегам, с последующей вставкой фрагментов в таблицу.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
  teg='ZAP';
  teg_begin='<'||teg||'>';
  teg_end  ='</'||teg||'>';
  teg_begin_len = char_length(teg)+2;
  teg_end_len = char_length(teg)+3;
  LEN = char_length(:body_zap);
  if (LEN = 0) then exit;
  POS = 1;
  while (POS <= LEN)
     do begin
         pos_begin=POSITION(teg_begin, :body_zap, pos);
         if (pos_begin=0) then leave;
         POS=POS_BEGIN+teg_begin_len;
         POS=POSITION(teg_end, :body_zap, pos)+teg_end_len;
         length_block=pos - pos_begin;
         strbody=substring(:body_zap from :pos_begin for :length_block);

    --          insert into ...........................;

        end



столкнулся с тем, что небольшие файлы (1-2 мб, 1000 - 1500 блоков) обрабатываются достаточно быстро 2-3 секунды,
однако при размере файлов в 35 мб 19200 блоков процедура просаживается в производительности без вставки, а только на цикл WHILE ... затрачивается более 40 минут.

FB 2.59, WIN 2003, сервер виртуальный, 4 ядра XEON 2.4 , памяти 8GB, подключение только моё
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39922624
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11,

временные блобы перестают помещаться в страничном кеше и начинают сбрасываться на диск
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39922625
Фотография crutchmaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11,

В чём смысл делать всё это именно на стороне FB?
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39922626
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис
zeon11,

временные блобы перестают помещаться в страничном кеше и начинают сбрасываться на диск


Ок, понятно. Спасибо.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39922629
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
crutchmaster
zeon11,

В чём смысл делать всё это именно на стороне FB?


Если это можно делать на сервере, зачем это делать ещё где-то?
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39922635
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис
zeon11,

временные блобы перестают помещаться в страничном кеше и начинают сбрасываться на диск
Это легко проверить - смотреть на рантайм статистику выполнения запроса (writes).
Если так, то попробовать увеличить кеш, пока writes не придут в норму.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39922641
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11,

потому что на клиенте будет быстрее, распарсить XML, подготовить запрос и сделать инсерт получившихся кусков
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39922658
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис
zeon11,

потому что на клиенте будет быстрее, распарсить XML, подготовить запрос и сделать инсерт получившихся кусков


Да, наверное, придётся так и делать. Раньше с малыми файлами разбирал XML исключительно на сервере. XML разбирался на полтора десятка таблиц, и разбирать на сервере было удобно, всё под рукой, но сейчас появились файлы до 90 мб, и всё резко просело по скорости.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39922665
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
Это легко проверить - смотреть на рантайм статистику выполнения запроса (writes).
Если так, то попробовать увеличить кеш, пока writes не придут в норму.
reads конечно, не writes
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39922681
Фотография crutchmaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис
потому что на клиенте будет быстрее, распарсить XML, подготовить запрос и сделать инсерт получившихся кусков

Да, и нагрузка уйдёт туда же. У сервера ресурсы не резиновые.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39922952
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А через udf не вариант? Либо отдельной службой
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39922961
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2А через udf не вариант?

нет конечно. UDF умеет возвращать только скалярный результат, т.е. набор данных из неё не вернуть.
Выполнять запросы в контексте текущего коннекта и транзакции там тоже нельзя.

В UDR (внешние ХП) можно и то и другое, но это в 3.0
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923066
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
crutchmaster
Симонов Денис
потому что на клиенте будет быстрее, распарсить XML, подготовить запрос и сделать инсерт получившихся кусков

Да, и нагрузка уйдёт туда же. У сервера ресурсы не резиновые.


Сервер на то и есть, чтобы нагрузку держать, тем более, такая работа планируется на ночь, когда он (сервер) пальцем в носу ковыряет.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923072
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2
А через udf не вариант? Либо отдельной службой


Симонов Денис
Василий 2А через udf не вариант?


нет конечно. UDF умеет возвращать только скалярный результат, т.е. набор данных из неё не вернуть.
Выполнять запросы в контексте текущего коннекта и транзакции там тоже нельзя.

В UDR (внешние ХП) можно и то и другое, но это в 3.0

UDF тут тоже работает, через UDF'ку разбираю элементарные блоки по значениям и разгоняю их по таблицам.
В UDF'ку для ускорения загоняю сразу список значений, что мне надо получить, соответственно из UDF'ки единоразово получаю список результатов.
Так что какой-то эрзац-набор данных в процедуре, всё-таки получаю.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923078
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11,

по идее, из-за офигенного количества временных блобов будет пухнуть база (потом пустое место будет переиспользоваться).
http://www.ibase.ru/dbgrowth/

а значит, чем быстрее диск, тем будет быстрее обработка. Обычно на виртуалках проблемы в основном с производительностю диска, кстати. На скорости проца и памяти падает, якобы, не более 5%. А вот на диске может быть много хуже.
Я бы проверил диск crystaldiskmark.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923079
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv
zeon11,

по идее, из-за офигенного количества временных блобов будет пухнуть база (потом пустое место будет переиспользоваться).
http://www.ibase.ru/dbgrowth/

а значит, чем быстрее диск, тем будет быстрее обработка. Обычно на виртуалках проблемы в основном с производительностю диска, кстати. На скорости проца и памяти падает, якобы, не более 5%. А вот на диске может быть много хуже.
Я бы проверил диск crystaldiskmark.


Да, статью эту читал, да и постоянно Ваш сайт пересматриваю. Спасибо за ресурс.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923089
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис
нет конечно. UDF умеет возвращать только скалярный результат, т.е. набор данных из неё не вернуть.
Выполнять запросы в контексте текущего коннекта и транзакции там тоже нельзя.

В UDR (внешние ХП) можно и то и другое, но это в 3.0

Так и не обязательно, можно и имеющимися средствами извратиться. Например, в цикле вызывать UDF с блобом и позицией, с которой начинать поиск. Пока не вернет пустую строку - повторять в цикле.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923113
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2
Симонов Денис
нет конечно. UDF умеет возвращать только скалярный результат, т.е. набор данных из неё не вернуть.
Выполнять запросы в контексте текущего коннекта и транзакции там тоже нельзя.

В UDR (внешние ХП) можно и то и другое, но это в 3.0

Так и не обязательно, можно и имеющимися средствами извратиться. Например, в цикле вызывать UDF с блобом и позицией, с которой начинать поиск. Пока не вернет пустую строку - повторять в цикле.


Тогда в UDF надо держать открытым объект, в данном случае TXMLDocument, и гонять его хендл из UDF в процедуру и обратно, и это будет работать скорее всего только на Classic. А может так вообще делать нельзя.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923230
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11
Тогда в UDF надо держать открытым объект, в данном случае TXMLDocument, и гонять его хендл из UDF в процедуру и обратно, и это будет работать скорее всего только на Classic. А может так вообще делать нельзя.

Да не, я имел в виду, чтобы udf делала только то, что сейчас делает процедура - извлекала куски из блоба в виде строки varchar.

Кстати, насчет размножения временных блобов неплохо бы в доки. А то только в тут https://www.ibase.ru/dbgrowth/ нашел, и то когда давал запрос целенаправленно.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923257
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2,

даже если написать свою версию UDF SUBSTRING которая возвращает VARCHAR(8191), то этот блоб придётся многократно открыть, прочитать и закрыть. Причём если блоб не поточный, то для поиска нужной позиции придётся каждый раз читать его с самого начала.
Но это хотя бы уберёт временные блобы.

О производительности разных решений. Недавно баловался с написанием внешних процедур на С++ (в качестве самообучения).
Написал собственную процедуру split_int для разделения больших BLOB. Суть теста генерируем числа от 1 до 1000000 и соединяем их агрегатной функцией LIST

скрипт
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
WITH RECURSIVE r
AS (SELECT
        0 AS n,
        1 AS g
    FROM rdb$database
    UNION ALL
    SELECT
        n + 1,
        r.g
    FROM r
    WHERE n < 999),
lst
AS (SELECT
       LIST(r1.n + r2.n * 1000, ';') AS b
    FROM r r1
    JOIN r r2 ON r1.g = r2.g)
SELECT
  count(*)
FROM lst



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
План
PLAN HASH (LST R RDB$DATABASE NATURAL, , LST R RDB$DATABASE NATURAL, )

Select Expression
    -> Aggregate
        -> Aggregate
            -> Filter
                -> Hash Join (inner)
                    -> Recursion
                        -> Table "RDB$DATABASE" as "LST R RDB$DATABASE" Full Scan
                        -> Filter
                    -> Record Buffer (record length: 41)
                        -> Recursion
                            -> Table "RDB$DATABASE" as "LST R RDB$DATABASE" Full Scan
                            -> Filter

------ Информация о производительности ------
Время подготовки запроса = 16ms
Время выполнения запроса = 625ms
Среднее время на получение одной записи = 625,00 ms
Current memory = 279 893 808
Max memory = 280 302 048
Memory buffers = 16 384
Reads from disk to cache = 0
Writes from cache to disk = 667
Чтений из кэша = 2 012


В результате получается блоб размером ~6 Мбайт. Теперь собственно разделение

тест split_int
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
WITH RECURSIVE r
AS (SELECT
        0 AS n,
        1 AS g
    FROM rdb$database
    UNION ALL
    SELECT
        n + 1,
        r.g
    FROM r
    WHERE n < 999),
lst
AS (SELECT
       LIST(r1.n + r2.n * 1000, ';') AS b
    FROM r r1
    JOIN r r2 ON r1.g = r2.g)
SELECT
    min(s.out_int) as min_int,
    max(s.out_int) as max_int
FROM lst
LEFT JOIN split_int(lst.b, ';') s ON TRUE



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
План
PLAN JOIN (HASH (LST R RDB$DATABASE NATURAL, , LST R RDB$DATABASE NATURAL, ), S NATURAL)

Select Expression
    -> Aggregate
        -> Nested Loop Join (outer)
            -> Aggregate
                -> Filter
                    -> Hash Join (inner)
                        -> Recursion
                            -> Table "RDB$DATABASE" as "LST R RDB$DATABASE" Full Scan
                            -> Filter
                        -> Record Buffer (record length: 41)
                            -> Recursion
                                -> Table "RDB$DATABASE" as "LST R RDB$DATABASE" Full Scan
                                -> Filter
            -> Filter
                -> Procedure "SPLIT_INT" as "S" Scan

------ Информация о производительности ------
Время подготовки запроса = 32ms
Время выполнения запроса = 1s 922ms
Среднее время на получение одной записи = 1 922,00 ms
Current memory = 279 914 400
Max memory = 280 302 048
Memory buffers = 16 384
Reads from disk to cache = 0
Writes from cache to disk = 667
Чтений из кэша = 4 010


1.992 - 0.625 = 1.367 c
Т.е. процедура разбила по разделителю 6 мегабайтный блоб за 1.4 секунды.
Сильно сомневаюсь что вы сможете получить подобный результат с помощью UDF или PSQL
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923287
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

Если не сложно, можешь запустить на этой же конфигурации разделение процедурой PSQL?
Чтобы окончательно развеять все сомнения.

Напомню процедуру
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
CREATE OR ALTER PROCEDURE LIST_TO_ROWS(
    LST BLOB SUB_TYPE TEXT)
RETURNS (
    ID INTEGER)
AS
  declare pos_ int;
  declare offset int = 1;
  declare beg int;
  declare buf varchar(30100);
begin
  if (lst is null) then exit; -- добавлено по подсказке vvm

  while (0=0) do begin
    buf = substring(lst from offset for 30100);
    pos_ = 1; beg = 1;
    while (pos_ <= char_length(buf) and pos_ <= 30000) do begin
      if (substring(buf from pos_ for 1) = ',') then begin
        if (pos_ > beg) then
          id = substring(buf from beg for pos_ - beg);
        else
          id = null;
        suspend;
        beg = pos_ + 1;
      end
      pos_ = pos_ + 1;
    end
    if (offset + pos_ - 2 = char_length(lst)) then leave;
    offset = offset + beg - 1;
    if (offset > char_length(lst)) then leave;
  end

  if (pos_ > beg) then
    id = substring(buf from beg for pos_ - beg);
  else
    id = null;
  suspend;
end

...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923290
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery,

вечером попробую. Я этот тест на домашней машине делал
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923293
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

Если всё с собой - можно на любой повторить :)
Главное ведь, чтобы на одной и той же.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923309
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery,

нет у меня на работе UDR той. Я же её писал для развлечения (самообучения), а не для продакшена.

Вот на другой машине

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
WITH RECURSIVE r
AS (SELECT
        0 AS n,
        1 AS g
    FROM rdb$database
    UNION ALL
    SELECT
        n + 1,
        r.g
    FROM r
    WHERE n < 999),
lst
AS (SELECT
       LIST(r1.n + r2.n * 1000, ',') AS b
    FROM r r1
    JOIN r r2 ON r1.g = r2.g)
SELECT
    min(s.id) as min_int,
    max(s.id) as max_int
FROM lst
LEFT JOIN list_to_rows(lst.b) s ON TRUE




Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
План
PLAN JOIN (HASH (LST R RDB$DATABASE NATURAL, , LST R RDB$DATABASE NATURAL, ), S NATURAL)

------ Информация о производительности ------
Время подготовки запроса = 0ms
Время выполнения запроса = 23s 510ms
Среднее время на получение одной записи = 23 510,00 ms
Current memory = 149 005 632
Max memory = 149 321 792
Memory buffers = 16 384
Reads from disk to cache = 0
Writes from cache to disk = 2 254
Чтений из кэша = 162 916

у меня дома конечно комп чуть по мощней, но не настолько же
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923358
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

То есть в 10 раз минимум. Спасибо.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923367
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery,

дома повторю. Если кому-то интересно могу выложить код процедуры на github.

Ничего удивительного в этом нет. В моей процедуре BLOB читается однократно (сразу все сегменты) в stream. Дальше я из stream получаю строку, а потом собственно разделяю на подстроки, каждая подстрока возвращается аналогом SUSPEND.

Я делал подобную процедуру и на Delphi, но там скорость была почти в 2 раза меньше. Видимо дорого преобразование string <-> ansichar[N]
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923374
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис
В моей процедуре BLOB читается однократно (сразу все сегменты) в stream. Дальше я из stream получаю строку, а потом собственно разделяю на подстроки, каждая подстрока возвращается аналогом SUSPEND.
Это требует много памяти.
Не пробовал читать блоб частями ?
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923418
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad,

была мысль обрабатывать обрабатывать частями по 32K. Помимо экономии памяти можно получить профит в виде досрочного прерывания всякими first/rows, так чтобы блоб не читался до конца
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923527
demon1992
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис
WildSery,

дома повторю. Если кому-то интересно могу выложить код процедуры на github.


Было бы интересно.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923664
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery,

а вот теперь list_to_rows на том же самом компьютере и БД

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
План
PLAN JOIN (HASH (LST R RDB$DATABASE NATURAL, , LST R RDB$DATABASE NATURAL, ), S NATURAL)

------ Информация о производительности ------
Время подготовки запроса = 16ms
Время выполнения запроса = 10s 359ms
Среднее время на получение одной записи = 10 359,00 ms
Current memory = 280 864 576
Max memory = 281 217 456
Memory buffers = 16 384
Reads from disk to cache = 0
Writes from cache to disk = 1 127
Чтений из кэша = 81 387
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923673
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

Лучше в виде статьи. Пусть даже самой простенькой.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923684
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vlad F,

дык писал уже, но не по плюсы

https://habr.com/ru/post/455375/
https://github.com/sim1984/udr-book
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923701
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

Теперь про плюсы. Пора уже их пропагандировать.)))
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923721
IBExpert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис

------ Информация о производительности ------
...
Current memory = 280 864 576
Max memory = 281 217 456
Memory buffers = 16 384
Reads from disk to cache = 0
Writes from cache to disk = 1 127
Чтений из кэша = 81 387


Кстати, кто даст внятный, но лаконичный перевод вот этого вот всего на русский, чтобы я забил в локализацию эксперта?
Например, Current/max memory - это что и в чем?
Reads\writes - это, я так понимаю, в страницах.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923734
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторКстати, кто даст внятный, но лаконичный перевод вот этого вот всего на русский, чтобы я забил в локализацию эксперта?
а оно действительно надо?
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923758
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IBExpertНапример, Current/max memory - это что и в чем?

в байтах конечно же. Главное не перевести Current как "текущая", а то стрёмно будет
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923763
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис
а вот теперь list_to_rows на том же самом компьютере и БД
Спасибо.

ЗЫ. Надеюсь, это "Fetch All" для обоих замеров? Уточню, на всякий случай.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923765
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery,

я же специально агрегатами min/max обвернул, чтобы там ровно 1 запись возвращалась
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39923767
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

А. Это я ещё кофе не выпил.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39924250
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladЭто требует много памяти.
Не пробовал читать блоб частями ?

попробовал.
Очень долго ломал голову, пока не вспомнил, что LIST очень забавно сегментирует блоб.
Я то наивно полагал, что прочитаю через getSegment столько байт сколько указываю.
Вроде была идея сделать так чтобы LIST возвращал потоковый блоб или передумали?
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39924286
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39924434
demon1992
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис,
Благодарю.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39927351
zeon11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Накидал в Lazarus функцию для клиента, может кому пригодится :

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
......
uses
  Classes, SysUtils, StrUtils, Forms, Dialogs, LConvEncoding, ComCtrls;

type
    TInsertXMLFunc = function(AXMLCut: AnsiString; var ANameFunction: String): boolean;
.....................................

class function TFileOMS.XMLChopper(AFile_Name:String; ATeg: AnsiString; AInsertXMLFunc: TInsertXMLFunc; AProgressBar: TProgressBar): integer;
var   CH : AnsiChar;  NameFunc: String;
      FText      : TFileStream;
      Length1, Length2 : integer;
      Teg1, Teg2, Value1, Value2, XMLCut: AnsiString;
begin
 Result:=0;
 try   //  ATeg:='PERS';
  Teg1:=ATeg+'>';  //  PERS>
  Teg2:='/'+Teg1; // /PERS>
  Length1:=Length(Teg1); //  5
  Length2:=Length(Teg2); //  6
  SetLength(Value1, Length1);
  SetLength(Value2, Length2);
  AProgressBar.Position:=0;
  FText:=TFileStream.Create(AFile_Name,fmShareDenyNone);   //открываем файл
  AProgressBar.Max:=FText.Size;
  FText.Seek(0,soFromBeginning);    //переходим в начало
  repeat
      FText.Read(CH,1);
      if (CH='<') then
        begin
           FText.ReadBuffer(Pointer(Value1)^, Length1);
           if Value1=Teg1   //   'PERS>'
             then begin
                    XMLCut:='<'+Teg1;   //  '<PERS>'
                    repeat
                        FText.Read(CH,1);
                        XMLCut:=XMLCut+CH;
                        if (CH='<') then
                           begin
                              FText.ReadBuffer(Pointer(Value2)^, Length2);
                              XMLCut:=XMLCut+Value2;
                              if Value2=Teg2  //   '/PERS>'
                                 then begin
                                       AProgressBar.Position:=FText.Position;
                                       if (not AInsertXMLFunc(XMLCut, NameFunc))
                                          then begin
                                                 XMLCut:=CP1251ToUTF8(XMLCut);
                                                 ShowMessage('В функции '+NameFunc+ ' неудачная вставка блока: '+ XMLCut);
                                                 exit;
                                               end;
                                        inc(Result);
                                        break;
                                      end
                           end;
                    until FText.Position>=FText.Size;
                  end;
        end;
  until FText.Position>=FText.Size;
 finally
     FreeAndNil(FText);
 end;
end;



Использование функции
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
function InsertXML_PERS_IntoFB(AXMLCut: String; var ANameFunction: String): boolean;
begin
   Result:=False;
   ANameFunction:='Добавление песональных данных в FB';
 //  Form_Main.SPxmlInsertZAP.ParamByName('XML_BODY_PERS').AsString:=CP1251ToUTF8(AXMLCut);   -- или
   Form_Main.SPxmlInsertZAP.ParamByName('XML_BODY_PERS').AsString:=AXMLCut;
   Form_Main.SPxmlInsertZAP.ExecSQL;
   Result:=true;
end;

procedure TForm_Main. .......................... ;
var InsertRecord: Integer;
begin
 try
......
      InsertRecord:=TFileOMS.XMLChopper(TmpDir+AFileOMS.NamePasp, 'PERS', @InsertXML_PERS_IntoFB, ProgressBar1);
  //    InsertRecord:=TFileOMS.XMLChopper(TmpDir+AFileOMS.NameMed, 'ZAP', @InsertXML_ZAP_IntoFB, ProgressBar1);

...................
      Memo1.Lines.Add('                Загружено в БД записей: '      +IntToStr(InsertRecord) );

 finally
     //
 end;

end;    



файл на 77 мб (42 785 записей) грузится в БД 10 мин

Клиентская машина - ноутбук, win 10, памяти 12гб, Core i7 4700HQ, 2.40GHz, про сервер писал выше.
Конечно, в процедуре-чоппере есть "вода", можно кое-что и выкинуть, но, думаю, радикально это скорость не повысит.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39927358
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11,

поищи готовый SAX parser для XML. Он как раз для случаев когда XML реально большой, чтобы не загружать всё дерево DOM в память.
...
Рейтинг: 0 / 0
substring BLOBа медленно
    #39927489
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zeon11

файл на 77 мб (42 785 записей) грузится в БД 10 мин

Читать по байту из файлстрима - не очень хорошая идея. Ну и там дальше много всего можно поулучшать
...
Рейтинг: 0 / 0
45 сообщений из 45, показаны все 2 страниц
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / substring BLOBа медленно
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]