powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Опять про varchar(n)
25 сообщений из 173, страница 4 из 7
Опять про varchar(n)
    #38719174
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисЕМНИП, ты ведь пытался что там с сортировкой сделать.
Нет, никогда я ничего такого не пытался, просто как-то предлагал простой хак для
использования имеющихся процедур сортировки для HASH GROUP.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38719180
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
гоните его нахер.
это мудозвон пустопорожний.
ибо сказано в писании: "один дурак может задать столько вопросов,
что и 100 мудрецов не ответят"
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38719245
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,
вот здесь это было. Там про уменьшение размеров сортировочных файлов разговор шёл.
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38719380
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисвот здесь это было.
Экий ты археолог... В плане "сделать" я там никакой активности не проявлял, только
"занести хотелку в трекер". Потом хотелка отсохла.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723703
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А всё-таки. Вот есть у нас таблица T(ID integer, S1 varchar(32000), S2 varchar(32000)).
Есть в ней одна запись: insert into T(ID, S1, S2) values(1, 'S1', 'S2').
Вопросы:
1. В чём профит от того, что в БД на эту запись лежат примерно 64000 байт, упакованных RLE?
Почему бы не записать всего пару десятков байт, закоденых RLE?
2. В чём профит от того, что при доставании записи из БД нужно будет выделить примерно 64000 байт, потом распаковать в них RLE-блок?
Почему бы не выделить пару десятков байт и не распаковать туда столько, сколько там реально данных?

Зачем сначала запаковывать, а потом распаковывать пустоту? Ведь при этом перерасходуется память (т.е. в итоге в кэш входит меньше полезных данных) + перерасходуется место на диске (а это лишний ввод-вывод) + впустую тратятся ресурсы процессора на работу с тем, что никогда не будет использоваться.
В чём профит такого подхода? Или это нужно Джима спрашивать почему он так заархитектурил тридцать лет назад? :)
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723718
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDee1. В чём профит от того, что в БД на эту запись лежат примерно 64000 байт,
упакованных RLE?
Почему бы не записать всего пару десятков байт, закоденых RLE?
С какого перепугу ты решил, что в БД лежит 64000 байт? Подикося, слышал об RLE только
название...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723722
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeА всё-таки. Вот есть у нас таблица T(ID integer, S1 varchar(32000), S2 varchar(32000)).
Есть в ней одна запись: insert into T(ID, S1, S2) values(1, 'S1', 'S2').
Вопросы:
1. В чём профит от того, что в БД на эту запись лежат примерно 64000 байт, упакованных RLE?
Почему бы не записать всего пару десятков байт, закоденых RLE?
2. В чём профит от того, что при доставании записи из БД нужно будет выделить примерно 64000 байт, потом распаковать в них RLE-блок?
Почему бы не выделить пару десятков байт и не распаковать туда столько, сколько там реально данных?
1. Потому что запись пакуется целиком, а не по отдельным полям. Одно "длинное" сжатие тупо быстрее десятка "коротких".
2. Чтобы не переаллокировать буфер каждый раз когда последующая запись окажется длиннее.

NickDeeВедь при этом перерасходуется память (т.е. в итоге в кэш входит меньше полезных данных) + перерасходуется место на диске (а это лишний ввод-вывод)
кеш тут вообще не причем, в нем лежат страницы со сжатыми данными. А для экономии места можно сжимать чуть хитрее.
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723750
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrА для экономии места можно сжимать чуть хитрее.
ты про это CORE-4401 говоришь?
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723758
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

так точно
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723811
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitr1. Потому что запись пакуется целиком, а не по отдельным полям. Одно "длинное" сжатие тупо быстрее десятка "коротких".

Запись пакуется целиком и так и так, она же в памяти непрерывно лежит. Просто я предлагаю не хранить хвостовые пробелы варчаров.
dimitr2. Чтобы не переаллокировать буфер каждый раз когда последующая запись окажется длиннее.Вот тесты переаллокации:

Код: 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.
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.
63.
64.
65.
66.
max alloc size: 128
1000000 reallocs: 13 ms
1000000 reallocs: 9 ms
1000000 reallocs: 8 ms
1000000 reallocs: 9 ms
1000000 reallocs: 8 ms
max alloc size: 256
1000000 reallocs: 25 ms
1000000 reallocs: 24 ms
1000000 reallocs: 24 ms
1000000 reallocs: 24 ms
1000000 reallocs: 23 ms
max alloc size: 512
1000000 reallocs: 33 ms
1000000 reallocs: 32 ms
1000000 reallocs: 32 ms
1000000 reallocs: 32 ms
1000000 reallocs: 33 ms
max alloc size: 1024
1000000 reallocs: 44 ms
1000000 reallocs: 43 ms
1000000 reallocs: 42 ms
1000000 reallocs: 42 ms
1000000 reallocs: 45 ms
max alloc size: 2048
1000000 reallocs: 67 ms
1000000 reallocs: 68 ms
1000000 reallocs: 66 ms
1000000 reallocs: 65 ms
1000000 reallocs: 66 ms
max alloc size: 4096
1000000 reallocs: 118 ms
1000000 reallocs: 119 ms
1000000 reallocs: 117 ms
1000000 reallocs: 118 ms
1000000 reallocs: 116 ms
max alloc size: 8192
1000000 reallocs: 253 ms
1000000 reallocs: 253 ms
1000000 reallocs: 255 ms
1000000 reallocs: 252 ms
1000000 reallocs: 252 ms
max alloc size: 16384
1000000 reallocs: 472 ms
1000000 reallocs: 470 ms
1000000 reallocs: 474 ms
1000000 reallocs: 469 ms
1000000 reallocs: 472 ms
max alloc size: 32768
1000000 reallocs: 845 ms
1000000 reallocs: 845 ms
1000000 reallocs: 845 ms
1000000 reallocs: 851 ms
1000000 reallocs: 845 ms
max alloc size: 65536
1000000 reallocs: 1578 ms
1000000 reallocs: 1570 ms
1000000 reallocs: 1572 ms
1000000 reallocs: 1567 ms
1000000 reallocs: 1572 ms
max alloc size: 131072
1000000 reallocs: 2976 ms
1000000 reallocs: 2968 ms
1000000 reallocs: 2958 ms
1000000 reallocs: 2961 ms
1000000 reallocs: 2960 ms


Вот код:
Код: 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.
program Project4;

{$APPTYPE CONSOLE}

uses
  System.SysUtils, Diagnostics;

var
  // будем переаллоцировать этот буфер из 1000 записей N раз (при N = 1000 получается 1 миллион переаллокаций),
  // с увеличивающимися MaxAllocSize(начиная с MaxAllocSize = 128 байт)
  Recs: array[0..1000-1] of Pointer; //

procedure ReallocRecs(MaxAllocSize: Integer);
var
  I: Integer;
begin
  for I := 0 to High(Recs) do
  begin
    Recs[I] := ReallocMemory(Recs[I], 20 + Random(MaxAllocSize-20));
  end;
end;

procedure ReallocNTimes(N: Integer; MaxAllocSize: Integer);
var
  I: Integer;
begin
  for I := 1 to N do
    ReallocRecs(MaxAllocSize);
end;

var
  I: Integer;
  SW: TStopWatch;
  N: Integer;
  MaxAllocSize: Integer;
begin
  Randomize;
  MaxAllocSize := 128;
  // first fill
  for I := 0 to High(Recs) do
    Recs[I] := GetMemory(20 + Random(MaxAllocSize-20));

  N := 1000;
  while True do
  begin
    Writeln(Format('max alloc size: %d', [MaxAllocSize]));
    for I := 1 to 5 do
    begin
      SW := TStopWatch.StartNew;
      ReallocNTimes(N, MaxAllocSize);
      Writeln(Format('%d reallocs: %d ms', [Length(Recs) * N, SW.ElapsedMilliseconds]));
    end;
    MaxAllocSize := MaxAllocSize * 2;
    if MaxAllocSize > 128 * 1024 then
      Break;
  end;
  Readln;
end.


Возможно в плюсах будет лучше.
dimitrNickDeeВедь при этом перерасходуется память (т.е. в итоге в кэш входит меньше полезных данных) + перерасходуется место на диске (а это лишний ввод-вывод)
кеш тут вообще не причем, в нем лежат страницы со сжатыми данными. А для экономии места можно сжимать чуть хитрее.
Или держать в памяти без хвостовых пробелов и не сжимать лишнего :)
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723863
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeВот тесты переаллокации
это сферический конь в вакууме. Реально будет потери времени выполнения процентов 10-20. Ты уверен, что их сэкономишь за счет сжатия "без хвостов"?
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723881
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrNickDeeВот тесты переаллокации
это сферический конь в вакууме. Реально будет потери времени выполнения процентов 10-20. Ты уверен, что их сэкономишь за счет сжатия "без хвостов"?
Не только сжатия, но и копирования. Одно дело копировать миллион блоков по 1000 байт, и совсем другое - миллион по 100.
Выделить миллион по 100 - это примерно 10 ms. Скопировать 100M - это в несколько раз быстрей чем скопировать 1000M. И даже +10 ms к "скопировать 100M" не будут существенны.
Возможно что выделить миллион по 900 + скопировать их будет уже где-то равным по скорости копированию миллиона по 1000.
Ещё нужно учесть что realloc нужно будет делать только если запись больше чем размер блока под неё.
Т.е. при фетче миллиона записей при максимальном размере записи N (что определяется в метаданных) в memory-buffer вмещающий лишь одну запись, мы получим много меньше чем N реаллоков (т.е. совсем даже не миллион).
Итого, нужно реаллоцировать только увеличивая размер буфера под одну запись (не уменьшая если следующая запись меньше), и копировать туда-оттуда только реально используемые байты, без хвоста. И имхо будет профит :)
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723894
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDee,

твои умозаключения основываются на какой-то абстрактной фигне. Исходники FB открыты возьми да и проведи эксперимент. Если удастся получить приличный выигрыш тогда можно что-о смело утверждать.
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723903
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeнужно реаллоцировать только увеличивая размер буфера под одну запись (не уменьшая если следующая запись меньше), и копировать туда-оттуда только реально используемые байты, без хвоста
тебе осталось додумать, как обращаться к полям, расположенным после урезанного варчара. Сейчас у них фиксированное смещение относительно начала записи. Станет плавающее. Менять еще и дескрипторы формата каждый раз когда читаем запись и когда меняем ее апдейтом в NEW-контексте? Уверен, что еще куча интересных вопросов вылезет, если копнуть поглубже.
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723920
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrNickDeeнужно реаллоцировать только увеличивая размер буфера под одну запись (не уменьшая если следующая запись меньше), и копировать туда-оттуда только реально используемые байты, без хвоста
тебе осталось додумать, как обращаться к полям, расположенным после урезанного варчара. Сейчас у них фиксированное смещение относительно начала записи.
Фиксированное смещение... Ну а по этому фиксированному смещению что расположено? Прям весь варчар? Если да, то предлагаю вместо этого разместить там четыре байта: первые два байта - длина варчара, вторые два - поинтер на его данные.
Так обращение будет быстрым.
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723921
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeТак обращение будет быстрым. И эти четырёхбайтовые описатели будут идти один за другим, т.е. доступ к ним будет индексный.
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723925
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDee,

вернулись к сжатию кучки маленьких буферов вместо одного большого
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38723987
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitr,

запись у нас расположена непрервыно.
Например есть табличка: int1, int2, int3, varchar1(1000), varchar2(1000), varchar3(1000), int4, varchar4(1000)
Запись в несжатом виде будет иметь вид:
[Header], [int, int, int, int, int, int, int, int], [данные varchar1(5 байт), данные varchar2(10 байт), данные varchar3(20 байт), данные varchar4(3 байта)].
В первых трёх int второго блока лежат значения int1, int2 int3.
В четвёртом int второго блока будет лежать "длина varchar1" и смещение по которому лежат данные этого varchar1(например относительно начала второго блока).
В пятом int второго блока лежит такая же информация про varchar2.
В шестом int второго блока лежит такая же информация про varchar3.
В седьмом int второго блока лежит значение int4.
В восьмом int второго блока лежит такая информация про varchar4.
Все три блока непрерывны внутри и лежат последовательно друг за другом, без разрывов.
Таким образом у нас будет один буфер для сжатия и разжатия.
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38724043
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDee,

и чем все это (включая переаллокации буфера записи) лучше, чем просто более эффективно сжимать хвосты? Не со степенью 64, а всегда в три-пять байт, например.
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38724558
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrNickDee,

и чем все это (включая переаллокации буфера записи) лучше, чем просто более эффективно сжимать хвосты? Не со степенью 64, а всегда в три-пять байт, например.
Эффективность сжатия влияет на размер данных в страничном кэше и в БД. А когда запись распаковывается для работы, например для сортировок, то там перерасход памяти: 16433678 .
Есть зависимость скорости создания индекса от объявленной длины поля, при одних и тех же данных (varchar(1) vs varchar(2048)): миллион записей, 1 секунда vs 18 секунд.
Засада везде :)
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38724585
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDee,

объясни две вещи:

1. На фига индекс по длинной предлинной строке
2. На фига сортировать по длинной предлинной строке

Другое дело что при сортировке сам резалтсет может получится широким даже при сортировки по небольшому ключу.
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38724598
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Дениспри сортировке сам резалтсет может получится широким даже при сортировки по небольшому ключу.Ога. И dimitr пару лет взад давал возможность потестировать некую спецсборку, где сортируются только ключики, а с итоговыми кортежами идёт их соединение по rdb$db_key.
Кому было интересно - тот попробовал, и теперь периодически спамит dimitr'a просьбой втыкнуть это в ФБ-3.х :-)
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38724601
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

я тоже её пробовал. Но тогда она во многих случаях промахивалась и весьма сильно. Будем надеется ДЕ доведёт оценку стоимости до ума, чтобы оптимизатор выбирал лучший алгоритм сорировки.
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38724659
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeЭффективность сжатия влияет на размер данных в страничном кэше и в БД.
и она примерно одинакова в обоих случаях

NickDeeА когда запись распаковывается для работы, например для сортировок, то там перерасход памяти
это вопрос к сортировщику, обсуждалось уже
...
Рейтинг: 0 / 0
Опять про varchar(n)
    #38724666
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денися тоже её пробовал. Но тогда она во многих случаях промахивалась и весьма сильно.
что значит "промахивалась"? Она в той сборке безусловно работала, насколько я помню.
...
Рейтинг: 0 / 0
25 сообщений из 173, страница 4 из 7
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Опять про varchar(n)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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