|
|
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Windows XP, Office XP Имеется: Код: plaintext 1. 2. 3. 4. 5. Требуется найти всех потомков какой-либо персоны (например 29) и записать их и номер поколения в таблицу потомки. Код: 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. При большем количестве производительнось катострофически падает. Так за 30 мин определяется около 2500 потомков. Посоветуйте, как существенно повысить производительность? Все имеющееся на форумах прочел... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.05.2004, 21:23 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Хорошо бы постановку задачи озвучить целиком. Типа есть то-то и то-то, получить надо вот это... А то не понятно почему именно такие таблицы. Или это какая-то классическая компоновка о которой все знают? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.05.2004, 22:08 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 lobodava Эти таблицы - часть генеалогической базы данных, отображающие родственные отношения. В общепринятом формате (так называемом GedCom стандарте) существуют два вида отношений: а) персона - семья родителей (отец и мать); б) персона - супруг(а) - дети. Эти отношения, имхо, отражают предложенные таблицы. М.б. можно и по другому... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.05.2004, 22:48 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Вау!!! А где почитать о GedCom стандарте? Ссылки есть? А то ни как не пойму как цепочка выстраивается из тех таблиц, что предложены. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.05.2004, 23:10 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Вижу логическую ошибку. Переменная rst As Recordset описана на уровне модуля, однако при каждом обращении к процедуре FindDescendant этой переменной заново делается Set и какое-то количество раз MoveNext. При возврате из очередного обращения к FindDescendant эта переменная уже имеет совершенно не то значение, которое было ей дано перед входом туда. По-моему, это должно вообще приводить к неправильной работе программы, а не то что к замедлению. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 00:15 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 lobodava Ссылок на стандарт можно найти мгого, только на английском. Например: The GEDCOM Standard Release 5.5 The GEDCOM Standard Release 5.5 (pdf) Кратко суть такова: В текстовом файле последовательно размещаются: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 08:42 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Владимиру Санычу авторПри возврате из очередного обращения к FindDescendant эта переменная уже имеет совершенно не то значение, которое было ей дано перед входом туда. Именно так! На этом и построен алгоритм: Код: plaintext 1. 2. 3. 4. В прилагаемом текстовом файле есть реальные таблицы. Можно было построить следующий алгоритм: Код: plaintext 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 09:09 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Но если написано Set rst = dbs.OpenRecordset... With rst Do While Not .EOF '***' .MoveNext то, наверно, .MoveNext и While Not .EOF должны относиться к тому же объекту, которому сделан Set. Однако в приведенной программе это не так, потому что в части '***' делается другой Set. Может, все-таки надо перенести Dim rst As Recordset внутрь процедуры? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:08 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
авторDim rst As Recordset внутрь процедуры? Саныч, утечку памяти это не предотвратит - что в лоб, что по лбу ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:19 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Почему не предотвратит? Просто будет несколько экземпляров рекордсета, но каждый будет закрываться когда ему положено. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:22 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
кто же его закроет, если ему это явно не сказано? А если сказано, то то и указатели в стеке плодить не обязательно - одного хватит, на уровне модуля. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:25 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Close надо добавить, это несомненно. Независимо ни от чего. Но одного не хватит, потому что они должны использоваться одновременно. Второй должен открываться прежде, чем закроется первый, и т.д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:30 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Саныч прав должно выглядеть так (чтобы рекордсеты разных поколений, и счетчики поколений в рекурсии были автономными) Код: 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. по мужу и жене наверное надо бы залудить индексы. Но на больших объемах все равно будут проблемы - как вы думаете, сколько стоит взять несколько десятков тысяч разных запросов (да, не дай бог, с предварительной оптимизацией)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:30 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Кстати! Вот если поставить Close, то тут-то и станет очевидно, что программа работает неправильно. Потому что после первого выполненного Close сразу начнутся сообщения об ошибках. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:31 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
то есть если ты про то, что процедура рекурсивный характер имеет (блин - должна иметь) - это несомненно. Но при этом рекордсет не обязателен. достаточно dcount-ом проверить, есть ли дети и и одним update-запросом. проставить им уровень. ЗЫ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:35 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Victosha: Полностью согласен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:37 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Саныч Стандарт! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:42 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Владимир Саныч, 2 Victosha Определенно вы друг-друга понимаете :) Я вас - нет :( Нельзя ли конкретизировать в виде кода? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:45 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
и самое главное. на размещение в памяти тысячи рекордсетов потребуется до шиша памяти. т.ч. может и имеет смысл обходиться одним рекордсетом, но по возвращении из рекурсии надо возобновлять _старый_ (т.е. _этого уровня_ наследственности) рекордсет, и вместо MoveNext ходить Find-ом на следующий. еще одно решение - сделать поле муж/жена общим (персона) (+ поле признака (тип) + уникальный индекс по 3-м полям (семья,персона,тип), открывать семью не запросом, а рекордсетом по указанному индексу и бегать seek-ом (по возвращении во внешний уровень переходить seek-ом на следующее значение индекса). (то же можно и при разных полях мух/жана, но пробегая процедуру по 2-м индексам (семья,муж), (семья,жена)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:48 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Код: 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. Это без учета того, что сказали фыыф и Victosha. Потому что они абсолютно правы, но это потребует более серьезных изменений. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:53 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Да, действительно, надо выбросить (многократные, и затратные) открытия рекордсетов из рекурсии. Открывать один раз один набор семей снаружи, как dbOpenTable, и при входе/возвращении на уровень изменять только параметры Seek-а (много быстрее чем Find), для чего озаботиться необходимыми индексами и переменными уровня рекурсивной процедуры для их текущего хранения. Это (для mdb) будет наискорейшим выходом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:00 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыв модификация - на ado открыь 2 client-side рекордсета, локально их индексировать, дальше и FindFirst (не вижу зачем) и Filter их будут успешно пользовать. Рекурсию придется линеаризировать циклами. ps кто ж такие "потомки" - что-то в "ТЗ" их не наблюдается ?.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:11 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Владимир Саныч Проверил работу твоего кода. Производительность не изменилась :( Кстати, объявление переменных в рекурсивных процедурах уменьшает память. Это не я сказал :) Рекомендуют объявлять их на уровне модуля. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:44 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Victosha авторкто ж такие "потомки" - что-то в "ТЗ" их не наблюдается ?.... Не пойму, в чем вопрос? Родитель > ребенок > его ребенок > и т.д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:47 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Я не говорил о производительности. Я говорил о правильности. Если несколько рекурсивно вызванных экземпляров процедуры пользуются одним и тем же экземпляром некой переменной, то возникает конфликт! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:49 |
|
||
|
|

start [/forum/topic.php?fid=45&msg=32507268&tid=1674665]: |
0ms |
get settings: |
6ms |
get forum list: |
14ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
159ms |
get topic data: |
6ms |
get forum data: |
2ms |
get page messages: |
35ms |
get tp. blocked users: |
1ms |
| others: | 197ms |
| total: | 424ms |

| 0 / 0 |
