powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Готовое решение для работы с деревьями.
16 сообщений из 41, страница 2 из 2
Готовое решение для работы с деревьями.
    #33241626
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
- приличная избыточность данных (вся доп. таблица)- ее б скажем не хранить, а стартовать в общую "переменную" табличного вида (обобщенную между коннектами времянку) при первом запросе к базе любого коннекта, и нехай себе висит (и перестраивается) только в памяти (размер то записи невелик). Может быть есть что-то в этом ключе?
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33241650
Paul Chabinsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. получить всех предков определенного элемента.
Код: plaintext
SELECT * FROM tree WHERE left <= $left AND right >= $right ORDER BY left
Рекурсии не нужны
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33241711
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Paul Chabinsky1. получить всех предков определенного элемента.
Код: plaintext
SELECT * FROM tree WHERE left <= $left AND right >= $right ORDER BY left
Рекурсии не нужнызначит помню правильно :)


Да, кстати:
Код: plaintext
1.
WHERE left > parent_left AND right < parent_right;
WHERE left <= $left AND right >= $right;  
если я правильно понимаю, это довольно неприятные условия для индекса (left,right) ? Видимо по лефт идет поиск по индексу, а по райт - уже фильтр?
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33241712
nostromo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кажется, если таблица в памяти мало места занимает, то на диске и подавно :)

Замечу, что в постгресе каждая строка таблицы сопровождается заголовком приличного размера, частенько превышающего размер пользовательских данных:
из документацииAll table rows are structured in the same way. There is a fixed-size header (occupying 27 bytes on most machines), followed by an optional null bitmap, an optional object ID field, and the user data. The header is detailed in Table 49-4. The actual user data (columns of the row) begins at the offset indicated by t_hoff, which must always be a multiple of the MAXALIGN distance for the platform...
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33242741
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nostromoКажется, если таблица в памяти мало места занимает, то на диске и подавно :)смысел не в месте в памяти, а в соотношениии цен дисковых операций к операциям в памяти. ( т.е. чисто физические 3-4 порядка -прим. для математиков именно этим кстати кажеца объяснялося модное стартование tempdb в память для мс-скуль 6.5 ) А поскольку все данные этой таблицы - исчисляемые, (изьыточные) - то и нет необходимости хранить их на диске (достаточно строить, но быстро и один раз, после старта)
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33242786
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, а по поводу хидеров - это кажеца повод хранить исчисляемую (избыточную, но необходимую для SQL выборок) иерархию в индексированных тестовых полях в виде .1.123.78987... - кол-во шапок на иерархию узла поджимаеца (даже если табличка иерархий будет отдельной от соб-сно дерева), правда апдейты пойдут с расщеплением поля, но, похоже, не сложным. (И еще - не потребуется ли обращенного индекса - т.е. (функционального?) индекса на обращенную строку?)
Что вы об этом думаете?
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33243532
nostromo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
4321смысел не в месте в памяти, а в соотношениии цен дисковых операций к операциям в памяти. (т.е. чисто физические 3-4 порядка
хорошо, согласен, однако такие оптимизации в проектах обычно проводятся в последнюю очередь, к тому же так можно что угодно ускорить, а не только Ваш алгоритм.

4321да, а по поводу хидеров - это кажеца повод хранить исчисляемую (избыточную, но необходимую для SQL выборок) иерархию в индексированных тестовых полях в виде .1.123.78987... - кол-во шапок на иерархию узла поджимаеца (даже если табличка иерархий будет отдельной от соб-сно дерева), правда апдейты пойдут с расщеплением поля, но, похоже, не сложным.
Честно говоря, работать с индексированными полями не приходилось, не знаю насколько это быстро. Память, конечно, экономится, но потерять в скорости, как мне кажется, можно прилично. Например, перевод из текста в число операция не самая быстрая, да и лишняя, т.к. память экономится только для маленьких значений (которых меньшинство): 4-х байтовое целое занимает до 10 байтов в десятичной десятичной и до 8 в шестнадцатеричной. В общем, здесь лучше индексированные целые поля.

4321(И еще - не потребуется ли обращенного индекса - т.е. (функционального?) индекса на обращенную строку?)
Это не понял, поясните.

Если мыслить масштабно, то, кажется, идеальный вариант для любого алгоритма, оптимизирующего работу с некторой структурой -- это соответствующий встроенный в систему индекс плюс оптимизатор, умеющий его эффективно использовать. Может, пора связываться с разработчиками или писать свое расширение? :)
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33243750
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nostromo Например, перевод из текста в число операция не самая быстрая ну в случае хранения иерархий в поле (hierarchy text;) запросы на вхождение будут иметь (скажем) вид
WHERE c.hierarchy LIKE t.hierarchy||'.*'
т.ч. преобразование типов тут не нужно. (оно потребуется только при заполнении hierarchy триггером - из числа в текст)

nostromo т.к. память экономится только для маленьких значений (которых меньшинство): 4-х байтовое целое занимает до 10 байтов в десятичной десятичной и до 8 в шестнадцатеричной. речь шла о экономии на шапках записей - но кажется вы о том, что потери из-за преобразования в строку их съедят?

nostromo 4321(И еще - не потребуется ли ... индекса на обращенную строку?)
Это не понял, поясните.мои извинения, - это ложный перенос идеи о 2-х индексах (pid,id)|(id,pid) (что удобно для поиска как предков так и потомков) на случай текстовой иерархии. Кажется индекс на обращенную строку не пригодится - предки ищутся так же как и потомки только таблицы меняются в LIKE местами.



_______
ЗЗЫ:
nostromoЕсли мыслить масштабно, то, кажется, идеальный вариант для любого алгоритма, оптимизирующего работу с некторой структурой -- это соответствующий встроенный в систему индекс плюс оптимизатор, умеющий его эффективно использовать. Может, пора связываться с разработчиками или писать свое расширение? :)а я вот не думаю, что тут пора "мыслить масштабно". Ибо...
Ибо обнаружил, что идея спотыкается на том, что при апдейте (пересадке веток) приходится прибегать к использованию конструкций вида
DELETE ... WHERE t.field IN(SELECT f FROM ....)
(или (t.f1,t.f2) IN( SELECT f1,f2 FROM....)
, а они даже для случая отсутствия зависимости сабселекта от полей внешних (к сабселекту) считаются неоптимально - а именно сабселект считается для каждой записи (я даже пытался подоткнуть туда STABLE ф-ю -думая обмануть природу - ан. фих). Т.ч. экономия метода частична - вставка веток - дело практически "бесплатное" (недорогое), но вот пересадка (даже терминалов, если не выделять их пересадку в отдельную ветку триггерного алгоритма) напрягает.

я конечно нашел, что можно обмануть эту проблему (почти на порядок - полтора на ~100 000 записях в иерархичке) составлением стрингов для IN(,,,,), но это, мне кажеца, "не дело" - неужто оптимизатору так трудно выяснить отсутствие зависимости сабселекта от полей выбираемой в селекте записи? Вот уж что действительно давно пора бы было от"оптимизировать" разработчикам...
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33245121
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4321 Paul Chabinsky1. получить всех предков определенного элемента.
Код: plaintext
SELECT * FROM tree WHERE left <= $left AND right >= $right ORDER BY left
если я правильно понимаю, это довольно неприятные условия для индекса (left,right) ? Видимо по лефт идет поиск по индексу, а по райт - уже фильтр?Да уж, прочесывать пол-дерева ради поиска нескольких элементов (родителей) кажется неэффективным.

4321это кажеца повод хранить исчисляемую (избыточную, но необходимую для SQL выборок) иерархию в индексированных тестовых полях в виде .1.123.78987...Вроде бы так сделано в ltree.

4321DELETE ... WHERE t.field IN(SELECT f FROM ....)Можно заменить на exists ( select 1 from ... where f=t.field ). Или приджоинить: http://www.postgresql.org/docs/8.0/static/sql-delete.html#AEN41779
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33245214
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeXa NalBat 4321DELETE ... WHERE t.field IN(SELECT f FROM ....)Можно заменить на exists ( select 1 from ... where f=t.field ). Или приджоинить: http://www.postgresql.org/docs/8.0/static/sql-delete.html#AEN41779Спасибо, посмотрю!
( Я как раз и хотел поругаца на отсутствие "ДИЛЕТА ... ФРОМ ДЖОНА" (як скажем в неких настольных вструментах типа аксеса). Тут, насколько я понял, омиттед фром в полной красе. Вот только дилет форм аутер джон так кажеца не реализуеца.)

Что касаеца exists - пробовал в первую голову, получил времена на полпорядка _хуже_, чем при 2-х id IN(Select ...) AND pid IN(Select ...). Пока (из опробованного) наискорейшее - сшивать строку IN(,,,,,) и выполнять EXECUTE (при малом количесве подчиненных срабатывает раз в 10 -15 быстрее чем с IN(SELECT ...), но не совсем понятно, что будет при очень больших строках (есть ведь наверное и ограничения на длину SQL инструкции? Пока проверял - при перемещении веток с ~280 потомками по иерархии работает).
Правда появилась идея (не сшивать строку) а напрямую делетить записи в plpgsql-ой ХП в цикле (в аксессе бы подобное в VBA делать не стал - заведомо плохо, но в plpgsql имеет смысл оттестировать для пробы).
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33245465
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
, сорри, не заметил: also it cannot handle self-joins. т.ч. джойн по омиттед фром нервенно курит у сторонке (мля)
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33245473
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4321, сорри, не заметил: also it cannot handle self-joins. т.ч. джойн по омиттед фром нервенно курит у сторонке (мля)Фихвам! Абманём за счет вью! (голь на видумки хитра)
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33246091
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 LeXa NalBat
к проблеме DELETE FROM ... WHERE IN(... ) на моих данных:

к сожалению нагрузка на сервер непостоянна. Т.ч. тестовые результаты различаются иногда на порядки по временам (на одних и тех же данных). Поэтому числа не привожу. Но примерно такое резюме (при подмене функций в триггере обновления предка узла дерева):

1.EXECUTE (... IN (\' ||с_подстановкой_наборов||\' ) ~ на порядок лучше изначального дилета.

2. цикл DELETE внутри лупа - близко по скорости к дилету по 1. (на ~ 280*3 записей в лупе). (очень может быть, что скорости дилетов по пп. 1. и 2. разнятся сильнее - в триггере есть еще и инсерты, дающие примерно такой же вклад, но радует хотя бы то, что не надо думать о предельной длине SQL строки)

3. дилет с "ommited from" джойном в WHERE с 2 видами (той же таблицы) - раза в 2-3 похуже 1 и 2

4. Очень хотелося неявно заджойнится на SETOF ф-ю. Но, кажется этого нельзя. Т.е. нельзя ни заполнить сетоф переменную в plpgsql, ни написать
функция($1).поле в WHERE. Можно видимо посмотреть в сторону времянки. Но времянки - это к сожалению не фонтан (дисковые операции).

ЗЫ: надо бы потестить чистые дилеты на модельных данных, на незагруженном сервере. неушто придеца дома
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33246188
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
43213. дилет с "ommited from" джойном в WHERE с 2 видами (той же таблицы) - раза в 2-3 похуже 1 и 2киньте пожалуйста explain
...
Рейтинг: 0 / 0
Готовое решение для работы с деревьями.
    #33246301
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeXa NalBat 43213. дилет с "ommited from" джойном в WHERE с 2 видами (той же таблицы) - раза в 2-3 похуже 1 и 2киньте пожалуйста explain как говорилося выше:(при подмене функций в триггере обновления предка узла дерева)где для случая джойна подставлялась:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE OR REPLACE FUNCTION public.f_delete_inherited_hierarchy_join(int4)
  RETURNS bool AS
'DECLARE
BEGIN
DELETE FROM t_parents 
	WHERE t_parents.pid = v_parents.pid 
		AND  v_parents.id = $1 
		AND t_parents.id = v_parents_.id		
		AND v_parents_.pid = $1;	
	
RETURN TRUE;
END;
'
  LANGUAGE 'plpgsql' STABLE STRICT;
для предка 74 имеется 3 прямых и 280 иерархических потомков
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
EXPLAIN ANALYZE DELETE FROM t_parents 
	WHERE t_parents.pid = v_parents.pid 
		AND  v_parents.id =  74  
		AND t_parents.id = v_parents_.id		
		AND v_parents_.pid =  74 ;	
QUERY PLAN
Merge Join  (cost= 11114 . 69 .. 11138 . 48  rows= 808  width= 22 ) (actual time= 105 . 38 .. 105 . 38  rows= 0  loops= 1 )
"  Merge Cond: (""outer"".pid = ""inner"".pid)"
  ->  Sort  (cost= 11085 . 65 .. 11092 . 47  rows= 2730  width= 18 ) (actual time= 105 . 16 .. 105 . 16  rows= 1  loops= 1 )
        Sort Key: public.t_parents.pid
        ->  Nested Loop  (cost= 0 . 00 .. 10929 . 83  rows= 2730  width= 18 ) (actual time= 0 . 40 .. 100 . 84  rows= 831  loops= 1 )
              ->  Index Scan using pid_id on t_parents  (cost= 0 . 00 .. 959 . 86  rows= 341  width= 4 ) (actual time= 0 . 18 .. 5 . 00  rows= 280  loops= 1 )
                    Index Cond: (pid =  74 )
              ->  Index Scan using t_parents_pkey on t_parents  (cost= 0 . 00 .. 29 . 14  rows= 7  width= 14 ) (actual time= 0 . 11 .. 0 . 30  rows= 3  loops= 280 )
"                    Index Cond: (t_parents.id = ""outer"".id)"
  ->  Sort  (cost= 29 . 05 .. 29 . 06  rows= 7  width= 4 ) (actual time= 0 . 17 .. 0 . 17  rows= 1  loops= 1 )
        Sort Key: public.t_parents.pid
        ->  Index Scan using t_parents_pkey on t_parents  (cost= 0 . 00 .. 28 . 95  rows= 7  width= 4 ) (actual time= 0 . 08 .. 0 . 09  rows= 1  loops= 1 )
              Index Cond: (id =  74 )
Total runtime:  105 . 81  msec
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Готовое решение для работы с деревьями.
    #35029927
MySQLCraft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что если ветка переедет на другой парент или промежуточные паренты вставить или удалить...
Потребуется обновление и переиндексация всех дочерних записей, а их в данной задаче в сотни раз больше чем парентов.

Интересно, что получилось в результате? Насколько работоспособна эта база и в какой предметной области применяется?
...
Рейтинг: 0 / 0
16 сообщений из 41, страница 2 из 2
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Готовое решение для работы с деревьями.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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