powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Медленная выборка блобов
16 сообщений из 16, страница 1 из 1
Медленная выборка блобов
    #40052579
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть такой запрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT
  fld."RDB$FIELD_NAME",
  fld."RDB$DESCRIPTION"
FROM
  rdb$relation_fields fld
WHERE
  fld."RDB$SYSTEM_FLAG" = 0 AND
  fld."RDB$RELATION_NAME" = UPPER(:table_name)

и такой перебор
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
IBSQL1.ExecQuery;
try
  LFldName := IBSQL1.FieldByName('RDB$FIELD_NAME');
  LFldDesc := IBSQL1.FieldByName('RDB$DESCRIPTION');
  while not IBSQL1.Eof do begin
    LStr := LFldName.AsString;
    LStr := LFldDesc.AsString;
    IBSQL1.Next;
  end;
finally
  IBSQL1.Close;
end;

запрос возвращает 52 записи. Общее время чтения 2.2 секунды (сеть не очень)

Теперь меняем запрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT
  fld.ЭRDB$FIELD_NAME",
  CAST(fld."RDB$DESCRIPTION" AS VARCHAR(256)) AS "RDB$DESCRIPTION"
FROM
  rdb$relation_fields fld
WHERE
  fld."RDB$SYSTEM_FLAG" = 0 AND
  fld."RDB$RELATION_NAME" = UPPER(:table_name)

общее время чтения 77 миллисекунды. Выигрыш в 30 раз.

Да, я знаю, про BlobID и про isc_get_segment, но 30 раз! Может можно пошаманить с конфигами? Где-то мне здесь попадался алгоритм передачи блобов, но сейчас найти не могу.

FB 3.0.7


С уважением, Vasilisk
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052583
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
> findstr ^^#[A-Z] firebird.conf|findstr Wire
#WireCryptPlugin = Arc4
#WireCrypt = Enabled (for client) / Required (for server)
#WireCompression = false

Полный текст:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
# Should connection over the wire be compressed?
# Client only value - server should follow client setting if connect using
# correct protocol (>=13).
#
# Per-connection configurable.
#
# Type: boolean
#
#WireCompression = false

Включается, понятное дело, на клиенте. Для внешних подключений (EDS) сервер тоже будет клиентом.
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052585
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_ Может можно пошаманить с конфигами?

это ничего не даст. Если при выборке обычных типов записи буфферизируются и префетчатся - можно поиграться с размером пакета.
С блобами это практически бесполезно. Ты же не супердлинные блобы передаёшь. То есть весь блоб скорее всего одним сегментом читается. Значит дело только в количестве сетевых пакетов, а с ними ничего не поделаешь.
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052587
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov,

ты думаешь он в DESCRIPTION сочинение пишет?
Я думаю это довольно короткие описания. Так что тут дело не в размере, а просто в раунд-трипах
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052589
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Теоретически можно отхакать компоненты доступа, если они по глупости вызывают
isc_blob_info(). Это сэкономит один раундтрип. Можно было бы пошаманить с размером буфера,
но он обычно достаточно большой. И самое главное - посмотреть а сколько в этих блобах,
собственно, сегментов. Какой-нибудь баг способен их записывать с умолчательным сегментом
80 символов.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052593
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
они по глупости вызывают isc_blob_info().
Вызывают. Чтобы узнать размер блоба и зарезервировать под него место. А потом такой код
Код: 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.
const
  DefaultBlobSegmentSize = 16 * 1024;

procedure ReadBlob(hBlobHandle: PISC_BLOB_HANDLE; Buffer: PByte; BlobSize: Long;
                   GDSLibrary : IGDSLibrary);
var
  CurPos: Long;
  BytesRead, SegLen: UShort;
  LocalBuffer: PByte;
begin
  CurPos := 0;
  LocalBuffer := Buffer;
  SegLen := UShort(DefaultBlobSegmentSize);
  while (CurPos < BlobSize) do
  begin
    if (CurPos + SegLen > BlobSize) then
      SegLen := BlobSize - CurPos;
    if not ((GDSLibrary.isc_get_segment(StatusVector, hBlobHandle, @BytesRead, SegLen,
                             LocalBuffer) = 0) or
            (StatusVectorArray[1] = isc_segment)) then
      IBDatabaseError(GDSLibrary);
    Inc(LocalBuffer, BytesRead);
    Inc(CurPos, BytesRead);
    BytesRead := 0;
  end;
end;


Dimitry Sibiryakov
Какой-нибудь баг способен их записывать с умолчательным сегментом
80 символов.
Там в поле максимум 50 символов. Так что блобы односегментные.

Ладно, все я понял. Спасибо
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052651
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Firebird-у не хватает флага типа "возвращать blob вместе с данными", чтобы получение содержимого blob не делало запросов к серверу. Непонятно, почему хранение blob-ов на странице с данными - хорошо, а передача их клиенту вместе с данными - плохо? Где тут логика?
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052661
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggory,

потому что, остальные типы данных имеют фиксированный размер и под них можно заранее выделить буфер нужного размера.
А с блобами не понятно, сколько надо
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052686
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
И самое главное - посмотреть а сколько в этих блобах,
собственно, сегментов. Какой-нибудь баг способен их записывать с умолчательным сегментом
80 символов.
Это не играет роли, при чтении блоба сетевой слой запрашивает у сервера 32КБ и выдаёт приложению сегменты из этого буфера.
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052688
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggory
Firebird-у не хватает флага типа "возвращать blob вместе с данными", чтобы получение содержимого blob не делало запросов к серверу.
Сделаешь ?

PS Это есть в планах, но с невысоким приоритетом
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052689
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Да, я знаю, про BlobID и про isc_get_segment, но 30 раз!
А время пинга у тебя насколько отличется от нормального (1-2 мс) ? Во сколько раз ?
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052691
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
ggreggory
Firebird-у не хватает флага типа "возвращать blob вместе с данными", чтобы получение содержимого blob не делало запросов к серверу.
Сделаешь ?

PS Это есть в планах, но с невысоким приоритетом
Добавлю - это можно очень легко сделать и на уровне приложения, придётся чуть усложнить запрос и логику клиента.
Но если оно ТАК жмёт, то можно и постараться для себя :)
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052694
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
Это не играет роли, при чтении блоба сетевой слой запрашивает у сервера 32 64 КБ и выдаёт приложению сегменты из этого буфера.
Поправил
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052701
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hvlad

Сделаешь ?

PS Это есть в планах, но с невысоким приоритетом
Добавлю - это можно очень легко сделать и на уровне приложения, придётся чуть усложнить запрос и логику клиента.


На ум приходит в SELECT-запросе запрашивать вместе с блобом еще и преобразованное в строку начало блоба, типа
Код: plsql
1.
2.
3.
4.
..
<BLOB>,
CAST(SUBSTRING(<BLOB> from 1 for ...) AS VARCHAR(...)) as BLOB_PREVIEW,
..


И в таблицах показывать это начало. Тогда при фетче не будет кучи запросов. А уже при детальном просмотре обращаться к основному полю.

В правильном ключе рассуждения?

hvlad

Но если оно ТАК жмёт, то можно и постараться для себя :)


"Исходники открыты, если нужна фича - бери и делай". Эту мысль я понял :)
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052708
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggory,

ключ - правильный, но не понятно - весь блоб попал в строку или нет.

Я бы делал как-то так:
Код: sql
1.
2.
CASE WHEN OCTET_LENGTH(BLOB)  > 256 THEN BLOB ELSE as F_BLOB,
CASE WHEN OCTET_LENGTH(BLOB) <= 256 THEN CAST(... AS VARCHAR(256)) ELSE as F_STR,


Какое поле не NULL, то и брать на клиенте.
Есс-но, возможны разные варианты, этот не панацея.

PS OCTET_LENGTH(BLOB) берёт длину в байтах из заголовка блоба, CHAR_LENGTH(BLOB) читает весь блоб для мультибайтовых кодировок.
...
Рейтинг: 0 / 0
Медленная выборка блобов
    #40052717
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hvlad

PS OCTET_LENGTH(BLOB) берёт длину в байтах из заголовка блоба, CHAR_LENGTH(BLOB) читает весь блоб для мультибайтовых кодировок.


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


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