powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / По планам
25 сообщений из 28, страница 1 из 2
По планам
    #40012282
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Приветствую знатоков и разработчиков!

Занимаюсь вопросом перехода с Firebird 1.5 на WI-V3.0.7.33374 Firebird 3.0.

Есть следующая таблица

Код: plsql
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.
CREATE TABLE TBL (
    FLD  INTEGER,
    ID   INTEGER
);

CREATE INDEX TBL_IDX_FLD ON TBL (FLD);
CREATE INDEX TBL_IDX_ID ON TBL (ID);

set term ^;
execute block
AS
  declare cnt integer;
  declare i integer;
  declare k integer;
begin
  i = 0;
  k = 0;
  cnt = 0;
  while (cnt < 100000) do
  begin
    insert into tbl(id, fld) values(:i, :k);
    i = i + 1;
    if (i > 5) then i = 0;
    k = k + 1;
    if (k > 4663) then k = 0;
    cnt = cnt + 1;
  end
  execute statement 'set statistics index TBL_IDX_FLD';
  execute statement 'set statistics index TBL_IDX_ID';
end^
commit^



Пытаюсь делать запрос

Код: plsql
1.
2.
select count(*) from tbl a where
    exists (select * from tbl b where b.id = 0 and a.fld = b.fld)



В WI-V1.5.6.5026 Firebird 1.5 получаю

PLAN (B INDEX (TBL_IDX_FLD))
PLAN (A NATURAL)

------ Performance info ------
Prepare time = 16ms
Execute time = 13s 625ms
Avg fetch time = 13 625,00 ms
Current memory = 33 030 024
Max memory = 39 871 552
Memory buffers = 3 000
Reads from disk to cache = 779
Writes from cache to disk = 0
Fetches from cache = 2 849 118

В WI-V3.0.7.33374 Firebird 3.0 получаю:

PLAN (B INDEX (TBL_IDX_FLD, TBL_IDX_ID))
PLAN (A NATURAL)

------ Performance info ------
Prepare time = 31ms
Execute time = 39s 204ms
Avg fetch time = 39 204,00 ms
Current memory = 29 546 384
Max memory = 31 280 352
Memory buffers = 3 000
Reads from disk to cache = 0
Writes from cache to disk = 0
Fetches from cache = 2 156 038

Не очень понятно, зачем тут используется индекс TBL_IDX_ID по полю, у которого всего 5 разных значений среди таблицы в 100 тыс записей.

Такой вариант работает в 45 раз быстрее:

Код: plsql
1.
2.
select count(*) from tbl a where
    exists (select * from tbl b where b.id+0 = 0 and a.fld = b.fld)



PLAN (B INDEX (TBL_IDX_FLD))
PLAN (A NATURAL)

------ Performance info ------
Prepare time = 32ms
Execute time = 953ms
Avg fetch time = 953,00 ms
Current memory = 29 546 928
Max memory = 31 280 352
Memory buffers = 3 000
Reads from disk to cache = 0
Writes from cache to disk = 0
Fetches from cache = 1 590 140

45 раз - это существенная разница. Есть какой-нибудь полу-автоматический способ решения подобных проблем?
...
Рейтинг: 0 / 0
По планам
    #40012284
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
27.10.2020 16:45, ggreggory пишет:
> Не очень понятно, зачем тут используется индекс TBL_IDX_ID по полю, у которого всего 5 разных значений среди таблицы в 100 тыс записей.

не очень понятно, нахер ты его создал...

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
По планам
    #40012292
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мимопроходящий

27.10.2020 16:45, ggreggory пишет:
> Не очень понятно, зачем тут используется индекс TBL_IDX_ID по полю, у которого всего 5 разных значений среди таблицы в 100 тыс записей.

не очень понятно, нахер ты его создал...



Это пример, демонстрирующий суть проблемы. В реальности это индекс внешнего ключа с одной таблицы на другую, кол-во записей в которых и их соотношение нельзя проконтролировать.
...
Рейтинг: 0 / 0
По планам
    #40012295
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggoryВ WI-V1.5.6.5026 Firebird 1.5 получаю
Execute time = 13s 625ms
Reads from disk to cache = 779
Fetches from cache = 2 849 118

В WI-V3.0.7.33374 Firebird 3.0 получаю:
Execute time = 39s 204ms
Reads from disk to cache = 0
Fetches from cache = 2 156 038

Я один думаю, что где-то в этих яблоках затесались апельсины?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
По планам
    #40012296
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggory,

статистику обновлял?
...
Рейтинг: 0 / 0
По планам
    #40012303
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис
ggreggory,

статистику обновлял?


Посмотрите повнимательнее, это есть в примере.

Dimitry Sibiryakov

Я один думаю, что где-то в этих яблоках затесались апельсины?..


1.5 Classic, 3.0 Super, кэш тоже разный. Но не думаю, что это повлияет на планы. Или нет? В любом случае вы можете запустить это пример у себя на своей версии сервера с вашими параметрами. Если у вас другие данные получатся - напишите!
...
Рейтинг: 0 / 0
По планам
    #40012309
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggory,

архитектура на план не влияет никак. Оптимизатор один.
...
Рейтинг: 0 / 0
По планам
    #40012313
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
27.10.2020 18:10, kdv пишет:
> архитектура на план не влияет никак. Оптимизатор один.

он статистику пытается пересчитывать "изнутри" процедуры.
а тут как раз есть варианты.
(недавно обсуждали)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
По планам
    #40012314
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мимопроходящий

27.10.2020 18:10, kdv пишет:
> архитектура на план не влияет никак. Оптимизатор один.

он статистику пытается пересчитывать "изнутри" процедуры.
а тут как раз есть варианты.
(недавно обсуждали)


Вот что у меня выдает

Код: plsql
1.
select i.rdb$index_name, cast(i.rdb$statistics as varchar(100)) from rdb$indices i WHERE i.rdb$relation_name = 'TBL'



WI-V3.0.7.33374 Firebird 3.0

TBL_IDX_FLD 0.0002144082391168922
TBL_IDX_ID 0.1666666716337204

WI-V1.5.6.5026 Firebird 1.5

TBL_IDX_FLD 0.0002144082391168922
TBL_IDX_ID 0.1666666716337204

Несколько раз туда-сюда пересчитывал.
...
Рейтинг: 0 / 0
По планам
    #40012318
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggoryMemory buffers = 3 000

Memory buffers = 3 000

1.5 Classic, 3.0 Super, кэш тоже разный.

Кто-то или врёт или добросовестно заблуждается.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
По планам
    #40012324
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

ggreggoryMemory buffers = 3 000

Memory buffers = 3 000

1.5 Classic, 3.0 Super, кэш тоже разный.

Кто-то или врёт или добросовестно заблуждается.


Что же вы все подвох везде ищете. Я запускал тест на первых двух попавшихся базах данных. Если вы не верите мне, запустите его у себя, предлагал же!
...
Рейтинг: 0 / 0
По планам
    #40012329
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вряд ли это имеет отношение к планам, но вот статистика:

WI-V3.0.7.33374 Firebird 3.0

Код: 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.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
TBL (550)
    Primary pointer page: 1254, Index root page: 1264
    Total formats: 1, used formats: 1
    Average record length: 11.50, total records: 100000
    Average version length: 0.00, total versions: 0, max versions: 0
    Average fragment length: 0.00, total fragments: 0, max fragments: 0
    Average unpacked length: 12.00, compression ratio: 1.04
    Pointer pages: 1, data page slots: 656
    Data pages: 656, average fill: 53%
    Primary pages: 656, secondary pages: 0, swept pages: 0
    Empty pages: 2, full pages: 653
    Fill distribution:
         0 - 19% = 2
        20 - 39% = 1
        40 - 59% = 653
        60 - 79% = 0
        80 - 99% = 0

    Index TBL_IDX_FLD (0)
        Root page: 1440, depth: 2, leaf buckets: 51, nodes: 100000
        Average node length: 4.03, total dup: 95336, max dup: 21
        Average key length: 2.05, compression ratio: 1.45
        Average prefix length: 2.92, average data length: 0.05
        Clustering factor: 100000, ratio: 1.00
        Fill distribution:
             0 - 19% = 1
            20 - 39% = 0
            40 - 59% = 0
            60 - 79% = 0
            80 - 99% = 50

    Index TBL_IDX_ID (1)
        Root page: 81493, depth: 2, leaf buckets: 50, nodes: 100000
        Average node length: 3.99, total dup: 99994, max dup: 16666
        Average key length: 2.00, compression ratio: 0.83
        Average prefix length: 1.67, average data length: 0.00
        Clustering factor: 3924, ratio: 0.04
        Fill distribution:
             0 - 19% = 0
            20 - 39% = 1
            40 - 59% = 0
            60 - 79% = 0
            80 - 99% = 49
WI-V1.5.6.5026 Firebird 1.5

Код: 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.
29.
30.
31.
TBL (484)
    Primary pointer page: 62957, Index root page: 62958
    Average record length: 11.50, total records: 100000
    Average version length: 0.00, total versions: 0, max versions: 0
    Data pages: 654, data page slots: 654, average fill: 53%
    Fill distribution:
         0 - 19% = 0
        20 - 39% = 1
        40 - 59% = 653
        60 - 79% = 0
        80 - 99% = 0

    Index TBL_IDX_FLD (0)
        Depth: 2, leaf buckets: 123, nodes: 100000
        Average data length: 0.00, total dup: 95336, max dup: 21
        Fill distribution:
             0 - 19% = 1
            20 - 39% = 0
            40 - 59% = 68
            60 - 79% = 48
            80 - 99% = 6

    Index TBL_IDX_ID (1)
        Depth: 2, leaf buckets: 144, nodes: 100000
        Average data length: 0.00, total dup: 99994, max dup: 16666
        Fill distribution:
             0 - 19% = 0
            20 - 39% = 0
            40 - 59% = 142
            60 - 79% = 0
            80 - 99% = 2
...
Рейтинг: 0 / 0
По планам
    #40012332
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggoryЕсли вы не верите мне, запустите его у себя, предлагал же!

Я верю. Но никак не могу понять смысла этого топика и что именно ты хочешь добиться.
http://www.ibase.ru/dataaccesspaths/ ты уже изучил?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
По планам
    #40012347
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я верю. Но никак не могу понять смысла этого топика и что именно ты хочешь добиться.


Я в надежде на какой-нибудь спасительный патч, который всё исправит. Ну типа update rdb$indices set rdb$statistics = 1 where rdb$statistics > 0.1

http://www.ibase.ru/dataaccesspaths/ ты уже изучил?


Читал давно, но подробно не изучал. Поизучаю подробнее, возможно появятся мысли.
...
Рейтинг: 0 / 0
По планам
    #40012348
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если вкратце, то оптимизатор в 1.5 и 2.х/3.х/4.х работает зело по-разному. В 1.5 он видит отличие в селективности более порядка и тупо выкидывает TBL_IDX_ID из рассмотрения. В более новых версиях он считает стоимость выборки как с одним индексом, так и с обоими. И в данном случае решает, что оба будут выгоднее. И для отдельного подзапроса это возможно и верно. А вот то, что он коррелированный и что условие b.id = 0 возвращает один и тот же битмап на каждую запись внешнего запроса - это не учитывается. Такова селяви. Пока что придется как-то с этим жить :-)
...
Рейтинг: 0 / 0
По планам
    #40012356
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dimitr
В более новых версиях он считает стоимость выборки как с одним индексом, так и с обоими. И в данном случае решает, что оба будут выгоднее.


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

По формуле из статьи (bestSel + (((worstSel - bestSel) / (1 - bestSel)) * bestSel)) / 2 в моём примере получается

( 0.0002144082391168922 + ((( 0.1666666716337204 - 0.0002144082391168922) / (1 - 0.0002144082391168922)) * 0.0002144082391168922)) / 2 = 0.000125

т.е. разница 0.000125 и 0.000214 не ахти какая большая, но с двумя индексами на порядок медленнее.

Просто уж очень много всяких FOREIGN KEYS со ссылкой на маленькие таблички, которые портят планы.
...
Рейтинг: 0 / 0
По планам
    #40012358
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggory

Просто уж очень много всяких FOREIGN KEYS со ссылкой на маленькие таблички, которые портят планы.


И делетов-апдейтов ID в этих маленьких табличках не делается никогда в жизни. Ну и на пуркуа тогда эти FK? Триггера на инсертах в большие таблицы со ссылками справятся с проверкой наличия записей в маленьких на ура и не будет гемора оптимизатору. В 1.5 они (эти FK) ему тоже крышу сносят время от времени. Не надо быть догматиком, надо чуйствовать свою задачу. Этто я не с высокой колокольни, тоже лет 10 назад изводил грехи молодости.
...
Рейтинг: 0 / 0
По планам
    #40012360
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Старый плюшевый мишка
Триггера на инсертах в большие таблицы со ссылками справятся с проверкой наличия записей в маленьких на ура и не будет гемора оптимизатору.


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

ggreggory

В реальности это индекс внешнего ключа с одной таблицы на другую, кол-во записей в которых и их соотношение нельзя проконтролировать .
...
Рейтинг: 0 / 0
По планам
    #40012365
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Старый плюшевый мишка

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


Да, наверное это единственный вариант в данной ситуации! Он хотя бы позволяет управлять индексом (создавать где надо и отключать где надо).
...
Рейтинг: 0 / 0
По планам
    #40012368
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggory
Старый плюшевый мишка

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


Да, наверное это единственный вариант в данной ситуации! Он хотя бы позволяет управлять индексом (создавать где надо и отключать где надо).


В запросе-то отключить существующий индекс через+0 не проблема. Но вот на действительно больших таблицах начинают тормозить инсёрты перестройкой FK, а на ресторе просто мрак на их создании.
...
Рейтинг: 0 / 0
По планам
    #40012477
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggory
Симонов Денис
ggreggory,

статистику обновлял?


Посмотрите повнимательнее, это есть в примере.


Вот теперь посмотрел внимательно.

Так у тебя в этом индексе 999994 значений равно 0 из 1000000.

У оптимизатора нет информации о распределении ключей (гистограмм), есть только селективность индекса. Селективность предполагает что ваши значения в ключах распределены боле менее равномерно. Он достаточно неплохая для этого индекса 0.1666666716337204
А вот если бы были гистограммы, то он бы обнаружил что реальная селективность для значения 0 плохая.
...
Рейтинг: 0 / 0
По планам
    #40012479
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис

Так у тебя в этом индексе 999994 значений равно 0 из 1000000.


Запрос
Код: plsql
1.
select id, count(*) from tbl group by 1


выдает

Код: plaintext
1.
2.
3.
4.
5.
6.
ID	COUNT
0	16667
1	16667
2	16667
3	16667
4	16666
5	16666
...
Рейтинг: 0 / 0
По планам
    #40012482
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggory,

походу я ещё сплю, пора кофе пить ((
...
Рейтинг: 0 / 0
По планам
    #40012531
pastor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ggreggory
Старый плюшевый мишка
Триггера на инсертах в большие таблицы со ссылками справятся с проверкой наличия записей в маленьких на ура и не будет гемора оптимизатору.


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

ggreggory

В реальности это индекс внешнего ключа с одной таблицы на другую, кол-во записей в которых и их соотношение нельзя проконтролировать .


когда-то заявлялось в фичах, что создание constraint не обязательно будет сопровождаться созданием индекса.
это до альфы тройки

не смогли найти внетранзакционного механизма контроля. обосновали, привели примеры нерешаемых косяков.

принял как данность, живу с никчемными индексами.

таблицы, имеющие малое количество записей, и не подлежащие изменениям пользователями (системные справочники - пол, тип алгоритма, тип проводки и пр.) превратил в int домены. и сделал справочник - имя_домена, значение, текст, примечание.
...
Рейтинг: 0 / 0
По планам
    #40012542
ggreggory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-
...
Рейтинг: 0 / 0
25 сообщений из 28, страница 1 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / По планам
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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