Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
Народ, это снова я :) Продолжая разбираться с PostgreSQL наткнулся на сложность, которую уже день не могу разрешить, хоть бьюсь изо всех сил... Дело в следующем: есть таблица Tasks для хранения информации о заданиях, а также TasksAssosiations для хранения информации о дочерних заданиях. То бишь, если в Task записано два задания с ID = 1, ID = 2, то, зная, что 2 - подтаск 1, в таблице TasksAssosiations будет записано: ParentTaskID = 1, ChildTaskID = 2. Пишу сейчас ф-цию удаления задания по ID. Хочу удалить все подтаски таска, а потом и этот таск. Но никак не получается найти решение... Если рекурсия плюс временная таблица, то при переходе уже на второй уровень сервак ругается, что такая времнная таблица уже есть (конечно, я создал её на первом уровне): Код: 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. Если же рекурсия и тип запись(RECORD), то я не знаю, как выбрать из записи SELECT'ом последний ID...: Код: 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. Последний код даже не компилится, ругается на две строчки: Код: plaintext 1. 2. 3. Видимо, нельзя так делать... Что посоветуете, господа? Я очень надеюсь на ваш опыт, он у вас есть... Не раз мне помогали в, казалось бы, безвыходных ситуациях... ОГРОМНОЕ спасибо заранее! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.04.2006, 23:57 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
Не проще ли на триггеры и каскадные внешние ключи возложить? Тогда достаточно будет просто удалить узел - а остальное пойдет по цепочке Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 04:03 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
Хм... честно говоря, с триггерами дела не имел никогда, но их предназначение мне известно - при определённых изменениях в таблице они активизируются и выполняют какие-то действия. Но мне кажется, то, что Вы предложили, не реализует в полной мере мною задуманное... Мне нужно при удалении из таблицы Tasks сначала удалить все связи из таблицы TasksAssosiations, а потом удалить этот task из таблицы Tasks. Но при удалении связей из таблицы TasksAssosiations необходимо рекурсивно так же удалить всех "детей" удаляемого таска. Таким образом, имея таблицы: Код: 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. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. При удалении таска с ID = 15, мы должны получить данные: Таблица Tasks(пишу только ID): 9 и 12. Таблица TasksAssosiations(пишу только ID): TaskParentID = 9, TaskChildID = 12. Так должно остаться, т.к. у таска 15 дети: 7,8,11, а у таска 7, в свою очередь, дети: 9, 10, 13. И их все рекурсивно надо удалить. Вот, что необходимо. Имхо, триггер этого не сделает... Хотя... затем я и тут, что знаний недостаточно. Вот, пытаю счастья... Надеюсь, поможете. Езё раз спасибо заранее! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 10:45 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
каскад конечно хорошо, и он сам создаст свои триггеры. триггеры тоже хорошо, но позаписно - долго при массовом удалении, а на стейтмент - не очевидно, что вызовется каскадно, и дольше при удалении одной записи (а не массы). если предполагается частое массовое удаление - то лучче наверное хранимка, но не рекурсивная, которая удалит все дочернии махом. В рекурсивной же нет ничо проще, как не используя темповую просто делетить. (что у вас и написано с небольшими ошибками, и не понятно на что вам темповая табличка - видимо для каких -то иных нужд?). для нерекурсиного скл по всем дочерним надо заранее позаботиться о его возможности - методов построения "нерекурсивного" дерева видимо не меньше 3-х. Но поддерживать все их надо триггерами либо хранимками. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 10:45 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
J-Pro Имхо, триггер этого не сделает...неверно. Вам достаточно в REFERENCE приписать ON DELETE CASCADE (сейчас у вас риференс ON DELETE RESTRICT - по умолчанию.) И нужные (констрайнт)триггеры создадуться и сами все за вас сделают. Попробуйте и увидите все натурно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 10:51 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
4321каскад конечно хорошо, и он сам создаст свои триггеры. триггеры тоже хорошо, но позаписно - долго при массовом удалении, а на стейтмент - не очевидно, что вызовется каскадно, и дольше при удалении одной записи (а не массы). Прошу прощения за назойливость, но что такое "каскад"? :) Я понял, что Вы имеете в виду эту запись: Код: plaintext 1. 2. 3. Но что она значит? В двух словах не могли бы пояснить? А доки я уже полистаю... Спасибо. 4321если предполагается частое массовое удаление - то лучче наверное хранимка, но не рекурсивная, которая удалит все дочернии махом. Хмм... Странно, раньше терпеть не мог рекурсию, а сейчас не представляю как организовать "бесконечное" удаление "детей у детей" без рекурсии? 4321В рекурсивной же нет ничо проще, как не используя темповую просто делетить. (что у вас и написано с небольшими ошибками, и не понятно на что вам темповая табличка - видимо для каких -то иных нужд?). Хм... Опять же странно, разве я написал с ошибками? Блин, ну почему Вы не указываете на них? :) А вообще, темповая таблица или рекорд нужны мне для того, чтобы запомнить всех детей перед тем, как я удалю связи. Ведь, связи между таблицами жесткие и я не удалю сначала таск из таблицы Tasks, а потом его связь TasksAssosiations. Мне надо сначала запомнить всех детей в эдакий массив, а потом по каждому ребёнку пройтись и проделать то же самое, понимаете? И вот как оное реализовать? 4321для нерекурсиного скл по всем дочерним надо заранее позаботиться о его возможности - методов построения "нерекурсивного" дерева видимо не меньше 3-х. Но поддерживать все их надо триггерами либо хранимками. Не, наверное, лучше рекурсия... тока вот с темповыми таблицами разобраться... Подскажите, а? Спасибо заранее! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:01 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
J-Proт.к. у таска 15 дети: 7,8,11, а у таска 7, в свою очередь, дети: 9, 10, 13. И их все рекурсивно надо удалить.вроде бы тут можно обойтись одной таблицей Код: plaintext 1. 2. 3. 4. 5. 6. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:07 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
4321 J-Pro Имхо, триггер этого не сделает...неверно. Вам достаточно в REFERENCE приписать ON DELETE CASCADE (сейчас у вас риференс ON DELETE RESTRICT - по умолчанию.) И нужные (констрайнт)триггеры создадуться и сами все за вас сделают. Попробуйте и увидите все натурно. Блин, так это то, что мне надо! PostgreSQL helpCASCADE specifies that when a referenced row is deleted, row(s) referencing it should be automatically deleted as well. А я, дурак, от незнания огороды городить начал... везде рестрикты ставил, блин... НО, как я заметил, это пройдёт только для одного уровня. Удалять детей надо по-любому. А, чтобы их выбрать - нужна та же рекурсия... и временная таблица. Разве нет? Ещё раз спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:08 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat J-Proт.к. у таска 15 дети: 7,8,11, а у таска 7, в свою очередь, дети: 9, 10, 13. И их все рекурсивно надо удалить.вроде бы тут можно обойтись одной таблицей Код: plaintext 1. 2. Спасибо. И обошёлся бы одной, да только один таск может иметь несколько детей, а так же один ребёнок сможет иметь несколько родителей. То бишь, многие-ко-многим, а оное реализуется лишь через связную таблицу... Вот. Жду ответа на написанное мной двумя сообщениями ранее... Очень жду. Спасибо заранее! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:12 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
J-ProНО, как я заметил, это пройдёт только для одного уровня. Удалять детей надо по-любому. А, чтобы их выбрать - нужна та же рекурсия... и временная таблица. Разве нет? Всмысле, что опять же перед удалением таска надо удалить всех его детей и их детей и т.д. А их надо запомнить в какую-то запись и брать по одной. Рекурсией плюс временные таблицы не получится, по причине, описанной выше. А рекорд - не могу сделать SELECT как из таблицы, чтобы последний результат давал мне... Или можно, может, сделать тип set of records? :) Я действительно, ещё многого не знаю... Жду помощи... Спасибо заранее! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:19 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
J-Proодин ребёнок сможет иметь несколько родителейудалять ребенка надо когда удалается единственный его родитель? то есть допустим у ребенка три родителя, удаляем одного родителя, затем удаляем другого, затем удаляем последнего и в этот момент должен удалиться ребенок, так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:28 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
J-Pro НО, как я заметил, это пройдёт только для одного уровня. Удалять детей надо по-любому. А, чтобы их выбрать - нужна та же рекурсия... и временная таблица. Разве нет?матьматьматьмать (по привыччке ответило экхо) а папробовать? (чем чухню то пИсать). каскад срабатывает на каждую запиздь, т.е. в дите он тоже сработает - сл-но - отработает рекурсивно. единственный минус - массовые операции удаления в табличке начнут тормозить (о чем уже писалось). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:32 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
J-Pro один ребёнок сможет иметь несколько родителей.это существенно. (т.е. просто каскадом тут не обойтись). каскад достаточен для удаления из таскс, из таска нужен триггер на Таскс примерно такой: AS' Удалить из ТАСК, где ТАСК.id = OLD.id И не существует в ТАСКС где ТАСК.id = OLD.id ' ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:45 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
4321 J-Pro НО, как я заметил, это пройдёт только для одного уровня. Удалять детей надо по-любому. А, чтобы их выбрать - нужна та же рекурсия... и временная таблица. Разве нет?матьматьматьмать (по привыччке ответило экхо) а папробовать? (чем чухню то пИсать). каскад срабатывает на каждую запиздь, т.е. в дите он тоже сработает - сл-но - отработает рекурсивно. единственный минус - массовые операции удаления в табличке начнут тормозить (о чем уже писалось). Прежде чем отвечать сюда я всё попробовал. В вышеприведённом примере заменил RESTRICT на CASCADE и получил результат: Таблица Tasks(пишу только ID): все, кроме 15 остались. Таблица TasksAssosiations(пишу только ID): все связи остались, кроме связей, в которых учавствовал 15-й таск. Т.е. дети 15-го остались и связи их тоже. А я хочу, чтобы было так: Таблица Tasks(пишу только ID): 9 и 12. Таблица TasksAssosiations(пишу только ID): TaskParentID = 9, TaskChildID = 12. Так должно остаться, т.к. у таска 15 дети: 7,8,11, а у таска 7, в свою очередь, дети: 9, 10, 13. И их все рекурсивно надо удалить. Так вот в хранимой процедуре DeleteTask я и хочу сделать рекурсивное удаление всех детей. За связи я уже не переживаю, т.к. вижу, что всех их удалит CASCADE. Но рекурсивно вызвать эту же хранимую процедуру для детей и прадетей таска 15 - мне просто необходимо. А чтобы это сделать, я должен узнать этих детей перед удалением 15-го таска(а, значит и всех его связей с детьми, раз стоит CASCADE). Понимаете? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:47 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat J-Proодин ребёнок сможет иметь несколько родителейудалять ребенка надо когда удалается единственный его родитель? то есть допустим у ребенка три родителя, удаляем одного родителя, затем удаляем другого, затем удаляем последнего и в этот момент должен удалиться ребенок, так? Гм... нет, честно говоря, этот момент я должен был проверить. Если больше одного родителя у ребёнка, то удаляем только родителя, ребёнка не трогаем, т.к. у него ещё есть родители. Но это легко проверить. Мне главное щас найти способ получения и чтения всех детей родителя... плюс рекурсия... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:50 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
мои извинения. каскад отработал бы для дерева - когда 1 предок на потомка, и он (связз) сидит в _той же таблице_. по поводу удаления детей - я выше привел логику триггера на удаление из таскс (удалять потомка при удалении последней связи). Может быть и другая логика - "удалять потомка при удалении любой связи", "делать потомка независимой задачей" и т.п.. Т.ч. вы оперделитесь :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:53 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
4321 J-Pro один ребёнок сможет иметь несколько родителей.это существенно. (т.е. просто каскадом тут не обойтись). каскад достаточен для удаления из таскс, из таска нужен триггер на Таскс примерно такой: AS' Удалить из ТАСК, где ТАСК.id = OLD.id И не существует в ТАСКС где ТАСК.id = OLD.id ' Это как раз для проверки на множество родителей, как я понял, да? Удалить только в том случае, если больше нет родителей. Но это же можно проверить и в хранимой процедуре, правильно? В общем, на эту тему я подумаю отдельно, думаю, что тут проблем не возникнет. Что насчёт рекурсии и временной таблицы, уважаемый 4321? Вы поняли суть моего вопроса в предпоследнем ответе Вам? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:53 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
4321мои извинения. каскад отработал бы для дерева - когда 1 предок на потомка, и он (связз) сидит в _той же таблице_. по поводу удаления детей - я выше привел логику триггера на удаление из таскс (удалять потомка при удалении последней связи). Может быть и другая логика - "удалять потомка при удалении любой связи", "делать потомка независимой задачей" и т.п.. Т.ч. вы оперделитесь :) Именно при удалении последнего потомка, Вы правы. Спасибо за триггер, я никогда их не писал, но смысл понял, попробую реализовать. Сейчас проблема не в этом... Думаю, теперь Вы понимаете, в чём? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 11:56 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
для удаления потомка при удалении любого родителя см триггер от фффф немного переделанный - ибо отрабатывает та таксксе Код: plaintext 1. 2. 3. 4. 5. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 12:00 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
J-ProГм... нет, честно говоря, этот момент я должен был проверить. Если больше одного родителя у ребёнка, то удаляем только родителя, ребёнка не трогаем, т.к. у него ещё есть родители. Но это легко проверить.да уж, специфицируйте пожалуйста задачу :) J-ProМне главное щас найти способ получения и чтения всех детей родителя... плюс рекурсия...так все-таки что вам нужно, получить или удалить? P.S.: кажется, что удаление можно сделать без самописных рекурсивных функций и временных таблиц примерно так, как написал фффф. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 12:02 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
извините, фсё переврал (смешались в кучу кони, люди) - поправляюсь. видимо так (логику уж проверьте сами): 4321для удаления потомка при удалении любого родителя см триггер от фффф ... Код: plaintext 1. 2. 3. 4. 5. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 12:08 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
4321извините, фсё переврал (смешались в кучу кони, люди) - поправляюсь. видимо так (логику уж проверьте сами): .... Ничего, мне нужны все попытки помочь. Спасибо за то, что пытаетесь. Теперь обьясню ситуацию: посмотрел доку по триггерам. Ничего сложного. Как я понял, фффф создаёт "поRECORDный" триггер, который выполняется уже ПОСЛЕ удаления. Отсюда первый вопрос: каскад уже сработает к моменту вызова триггера? Т.е. когда вызовется триггер, в таблице ассоциаций тасков уже не будет тех записей, в которых присутствовал удалённый таск? Иными словами, мы никак не узнаем информацию о детях и родителях этого удалённого таска? Второй момент: писать триггер - всё равно, что писать хранимую процедуру. В том плане, что триггер нужен больше для того, если я работаю на уровне обычных SQL-запросов. Я же вызываю одни хранимые процедуры, у меня нет ни одного вызова простого запроса. А по сему, наверное, можно описать необходимые действия и в хранимой процедуре DeleteTask, ведь так? Это всё равно, что триггер, я могу делать в ней любые действия до того, как непосредственно вызову запрос: DELETE FROM Tasks. А сделать должен всё то же(используя вышеописанный код таблиц(где вместо RESTRICT стоит CASCADE) и предполагая, что удаляем таск 15, вызывая ф-цию DeleteTask(15)): 1. Удаляем всех детей. выбираем из таблицы TasksAssosiations все ChildTaskID, у которых ParentTaskID = 15 и сохраняем куда-то в виде таблицы или массива ID. В данном случае это будет: 7, 8, 11. Это мы нашли детей 15-го таска. в цикле, от 0 до 2 (или от 1 до 3) бежим по этим детям и вызываем для каждого рекурсивно эту же функцию, т.е. DeleteTask(7), DeleteTask(8), DeleteTask(11). 2. Удаляем сам таск 15, у которого больше нет детей, но, возможно есть родители, которых не нужно трогать, просто оставив их без связи с удалённым 15-м (как? см. ниже) после выхода из цикла можем окончательно удалить таск 15. При этом удалении из таблицы TaskAssosiations, благодаря CASCADE, автоматически удалятся все связи таска 15 с возможными его родителями БЕЗ удаления последних. Что мне и надо. Так проблема яснее, народ? Алгоритм налицо. Теперь вернусь к первоначальному вопросу: какой тип данных мне использовать для хранения и извлечения детей удаляемого таска (первый подпункт первого пункта)? Спасибо вам всем заранее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 12:54 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
J-Pro1. Удаляем всех детей. выбираем из таблицы TasksAssosiations все ChildTaskID, у которых ParentTaskID = 15 и сохраняем куда-то в виде таблицы или массива ID. В данном случае это будет: 7, 8, 11. Это мы нашли детей 15-го таска. в цикле, от 0 до 2 (или от 1 до 3) бежим по этим детям и вызываем для каждого рекурсивно эту же функцию, т.е. DeleteTask(7), DeleteTask(8), DeleteTask(11). Теперь вернусь к первоначальному вопросу: какой тип данных мне использовать для хранения и извлечения детей удаляемого таска (первый подпункт первого пункта)? Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 13:30 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
Подумал над последствиями CASCADE и надумал вот такой вариант: Код: 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. Только он почему-то не пашет... Не ругается, компилится нормально, в дебагере проходит нормально, из цикла выходит, но таски не удаляет почему-то... странно. А больше никто ничего не может предложить, народ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 13:33 |
|
||
|
Рекурсия + временные таблицы
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat Код: plaintext 1. 2. Согласен, так же, как у меня, только намного рациональнее. Но результат тот же самый - дебагером всё проходит отлично, из цикла выходит, но ни одной записи из таблиц не удаляется. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2006, 13:42 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=33691630&tid=2006447]: |
0ms |
get settings: |
12ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
40ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
35ms |
get tp. blocked users: |
1ms |
| others: | 235ms |
| total: | 352ms |

| 0 / 0 |
