SASGIS - SAS.Планета
View Issue Details
0001039SAS.ПланетаРефакторингpublic10-11-2011 14:1927-07-2015 14:27
volos 
zed 
normalmajoralways
resolvedfixed 
Windows7Ultimate
110418 
150915150915 
0001039: Тормоза с ростом количества меток и массы файла marks.sml
С ростом количества меток и увеличением массы marks.sml увеличиваются тормоза при редактировании меток. У меня сейчас файл marks.sml более 100Mb. Так сохранение измененной или новой метки длится более 2 мин.

Возможна ли оптимизация процесса? Жутко напрягает.
sml, SQLite, БД, метки
related to 0001481closed vasketsov SACS.Планета Переделка хранилища меток 
Issue History
10-11-2011 14:19volosNew Issue
10-11-2011 19:51gpsMaxCategoryБаг => Рефакторинг
10-11-2011 20:56gpsMaxTag Attached: sml
11-11-2011 09:09zOnNote Added: 0004348
11-11-2011 13:55feyaNote Added: 0004350
11-11-2011 14:37PapazolNote Added: 0004351
11-11-2011 17:46zOnNote Added: 0004354
11-11-2011 18:25GarlNote Added: 0004356
11-11-2011 18:27zOnNote Added: 0004357
11-11-2011 21:22gpsMaxNote Added: 0004360
29-11-2011 12:51sheavyNote Added: 0004452
08-12-2011 12:53TolikStatusnew => acknowledged
09-01-2012 09:42zOnNote Added: 0004815
09-01-2012 16:49TolikNote Added: 0004818
10-01-2012 09:51zedNote Added: 0004831
12-01-2012 05:26zOnNote Added: 0004873
12-01-2012 17:57DJ VKNote Added: 0004900
12-01-2012 17:58DJ VKNote Edited: 0004900bug_revision_view_page.php?bugnote_id=4900#r2433
12-01-2012 18:00DJ VKNote Edited: 0004900bug_revision_view_page.php?bugnote_id=4900#r2434
12-01-2012 18:07zOnNote Added: 0004901
12-01-2012 18:13GarlNote Added: 0004904
13-01-2012 05:10TolikNote Added: 0004921
13-01-2012 07:39vdemidovNote Added: 0004932
29-02-2012 11:47TolikNote Added: 0005742
09-08-2012 06:51vdemidovProduct Version.Nightly => 110418
12-08-2012 12:21gpsMaxRelationship addedrelated to 0001481
23-06-2015 19:34zedNote Added: 0016061
23-06-2015 19:34zedAssigned To => zed
23-06-2015 19:34zedStatusacknowledged => assigned
23-06-2015 19:35zedTag Attached: SQLite
23-06-2015 19:35zedTag Attached: БД
23-06-2015 19:35zedTag Attached: метки
23-06-2015 19:36zedTarget Version => 150915
23-06-2015 20:11vasketsovNote Added: 0016062
23-06-2015 20:18zedNote Added: 0016063
23-06-2015 20:46vasketsovNote Added: 0016064
23-06-2015 21:02zedNote Added: 0016065
23-06-2015 21:35vasketsovNote Added: 0016066
24-06-2015 05:19zedNote Added: 0016067
24-06-2015 07:59vasketsovNote Added: 0016068
24-06-2015 08:04zedNote Added: 0016069
24-06-2015 08:44vasketsovNote Added: 0016071
02-07-2015 13:42zedNote Added: 0016093
11-07-2015 07:41zedNote Added: 0016122
11-07-2015 11:37vasketsovNote Added: 0016123
11-07-2015 12:07zedNote Added: 0016126
11-07-2015 12:15vasketsovNote Added: 0016127
11-07-2015 12:21zedNote Added: 0016129
11-07-2015 12:26vasketsovNote Added: 0016131
11-07-2015 12:29zedNote Added: 0016132
11-07-2015 12:40vasketsovNote Added: 0016134
11-07-2015 12:52zedNote Added: 0016135
11-07-2015 13:33vasketsovNote Added: 0016137
11-07-2015 13:37vasketsovNote Edited: 0016137bug_revision_view_page.php?bugnote_id=16137#r6649
15-07-2015 12:00zedNote Added: 0016164
15-07-2015 12:00zedStatusassigned => resolved
15-07-2015 12:00zedFixed in Version => 150915
15-07-2015 12:00zedResolutionopen => fixed
15-07-2015 19:41zedNote Added: 0016165

Notes
(0004348)
zOn   
11-11-2011 09:09   
думаю, что пора менять формат меток, т.е. переходить от одного файла sml к древовидной структуре, т.е. категория/подкатегория = папка/подпапка, а метка = файл kml/kmz/sml. либо mysql прикручивать (заодно решится проблема мультидоступа).
это всё ИМХО.
(0004350)
feya   
11-11-2011 13:55   
zOn, на самом деле можно не так координально, достаточно использовать более быстрый парсер xml.
(0004351)
Papazol   
11-11-2011 14:37   
Файл меток должен весь открыться, то есть поместиться в память? 100 МБ - это прилично. Вполне может задействоваться подкачка, а это всегда тормоза. А при редактировании размер в памяти может и удвоиться. Плюс фрагментация...
(0004354)
zOn   
11-11-2011 17:46   
feya, можно, но ч/з 2-3 года у людей накопится СТОЛЬКО меток, что уже и более быстрый парсер фиг справится. если уж переделывать, то капитально.
(0004356)
Garl   
11-11-2011 18:25   
как только появится древовидная структура - метки будут расти в такой прогрессии что даже 300Мб будет не предел.

сейчас лично меня сдерживает то что в категорий будет столько что долго будет искать.
(0004357)
zOn   
11-11-2011 18:27   
если это не будет вызывать проблем, то хоть Гиг.
(0004360)
gpsMax   
11-11-2011 21:22   
Вариант в порядке фантазии: все метки в БД. Планета при смене видимой области делает запрос к базе, и визуализирует ответ.
(0004452)
sheavy   
29-11-2011 12:51   
согласен с gpsMax. БД - это best practice для этой задачи
(0004815)
zOn   
09-01-2012 09:42   
а может метки в Беркли попробовать хранить? раз уж прикрутили БДБ.
(0004818)
Tolik   
09-01-2012 16:49   
Отличная идея!
Только надо предусмотреть возможность использования файлов sml или БД.

Насколько сложно реализовать то, что написал gpsMax? Или можно считывать все метки в память, как и сейчас(?)
(0004831)
zed   
10-01-2012 09:51   
В Беркли по-моему будет не очень, потому как там нету "умных" селектов типа "дай мне все метки что попадают в полигон". А вот какой-нить SQLite вполне сгодился бы.
(0004873)
zOn   
12-01-2012 05:26   
вот хоть убейте, но всё же я за древовидную структуру.
ведь на сколько удобно станет работать с метками: папка-категория, подпапка-подкатегория, файл-метка.
правда работа САС с этим деревом вызывает вопросы.
я просто помечтал )
(0004900)
DJ VK   
12-01-2012 17:57   
(edited on: 12-01-2012 18:00)
А жуткие тормоза при выделении области это связанный баг? Если в старой версии ткнул левой кнопкой и начал выделение, то в новых надо ткнуть и подождать НЕ ШЕВЕЛЯ МЫШЬ пока не появится полигон. Ну я понимаю карту заполнения штормит в новых версиях, понятно что перебор по спирали дольше линейного. Но тут то что? Тормоза тоже страшнейшие, уж если выбран режим выделения, то чего там такого ждется то?
Или новый баг открыть?

(0004901)
zOn   
12-01-2012 18:07   
а на пустой копии тоже тормоза?
(0004904)
Garl   
12-01-2012 18:13   
>А жуткие тормоза при выделении области это связанный баг?
у меня полёт нормальный
(0004921)
Tolik   
13-01-2012 05:10   
у меня тоже полигон появляется мгновенно
(0004932)
vdemidov   
13-01-2012 07:39   
>А жуткие тормоза при выделении области это связанный баг?
Скорее всего это связано с тем, что процессор занят рендерингом меток. Попробуйте отключить отображение меток перед началом выделения.
(0005742)
Tolik   
29-02-2012 11:47   
Загрузил kml из 0001090, файл меток вырос до 90 МБ.
Работает всё нормально (ура!), но САС открывается и _закрывается_ очень долго.
При закрытии создаётся новый файл marks.sml и в него долго всё пишется.
Может быть, добавить такое условие: если метки не изменялись, новый файл не создавать?
(0016061)
zed   
23-06-2015 19:34   
Появилось время и желание прикрутить SQLite для меток, чем и занимался последнюю неделю. В самое ближайшее время надеюсь доделать, а пока, показываю то, что можно уже щупать: SASPlanet.SQLiteDB.zip

Из недоделок:
- не работает редактирование меток (нельзя поменять имя, перенести в другую категорию или изменить полигон)
- новый тип меток зашит в коде и из гуя нельзя включить назад sml
- ???

При запуске оно на старые метки вообще внимания не обращает и никак их не трогает. Но импорт работает, так что можно загнать свою базу в новый формат и посмотреть, как оно будет шевелиться (а оно шевелится весьма прилично).
(0016062)
vasketsov   
23-06-2015 20:11   
>а оно шевелится весьма прилично
Ещё бы )))

>в новый формат
Описание есть? Модель?
Я так понял, с моей моделью SQLite-меток несовместимо (как минимум есть таблица MarkGeometryRect).
Так что предлагаю сделать разные расширения, чтобы можно было оба варианта поддерживать.
(0016063)
zed   
23-06-2015 20:18   
Есть описание: t_MarkSystemModelORM.pas
Модель сильно упрощённая да и реализована человеком, слабо знакомым с SQL. Страшно сказать, но во всей реализации новых меток, мне пришлось написать всего 1 настоящий SQL запрос (для поиска по R-Tree). Вся работа идёт через фреймворк, что накладывает свой отпечаток. А на голом SQL я бы просто не осилил, поэтому деваться некуда.
(0016064)
vasketsov   
23-06-2015 20:46   
Я уже запустил EXE и получил "пустой" файл Marks.db3 размером 100 кил.
Поскольку кода создания таблиц в залитом патче нет, я пришёл к выводу, что всё это делает фреймворк. Что, собственно, ты и подтвердил.
Вообще если фреймворк по тем скруктурам, на что ты дал ссылку, генерит такой вменяемый код SQL, он как минимум достоин внимания.

>Модель сильно упрощённая
Да я вижу по скриптам, которые генерит SQLiteMaestro для этого файла. По сути, ты взял плоскую структуру SML и добавил видимость по пользователям (соответственно отделил метки от видимости меток, а категории - от их видимости, то есть, отделил данные от их отображения). В принципе - необходимый минимум для многопользовательности. Допилишь - метки будут просто летать.

>на голом SQL я бы просто не осилил
А я вот наоборот ))) но тут что кому понятнее.

У меня в общем-то вот какие вопросы. Не в смысле, что на них надо тебе срочно ответить, а скорее вопросы на будущее, как оно себя покажет:
1. ХЗ как этот фреймворк себя покажет, когда надо будет добавить поле в таблицу или новый индекс сделать, а не просто создать отсутствующие таблицы.
2. Скорость работы с R-tree - как закончишь, я бы вкорячил себе (правда, без ORM наверное всё же, хотя хз) и сравнил по счётчикам на идентичных данных (пусть модель сложнее и данных по каждой метке и категории больше, но хотелось бы зафиксировать кардинальное ускорение с R-tree).
3. Аналогично что касается FTS.
(0016065)
zed   
23-06-2015 21:02   
1. Поля добавляет нормально. Индексы не проверял, но тоже не должно быть проблем.
2,3. Про скорость - ХЗ, вроде нормально. SACS по-моему работает так же, если не быстрее (по ощущениям), так что там RTree может и не нужен. И с FTS я на грабли встал - он оказался чувствителен к регистру для русского текста. Я сперва имя и описание метки прямо там хранил, но поиск плохо работал и пришлось продублировать текстовые поля. Теперь они хранятся в оригинале, в метке, и в нижнем регистре, в индексе.
(0016066)
vasketsov   
23-06-2015 21:35   
>SACS по-моему работает так же, если не быстрее (по ощущениям)
Вообще довольно странно, если так.
В общем случае в SACS надо 6 запросов, чтобы получить видимые метки для экрана.
Если не использовать ссылки (links) - то только три.
Потому что там хранение разных типов меток (точнее, геометрии) разнесено по разным таблицам (в принципе, я могу и одним запросом всё вытащить, но это будет очень большой запрос))))).
А у тебя - нет, всё вместе.

Быстрее у меня может быть только в том случае, если накладные расходы внутри использованного тобой фреймворка большие. И в принципе, по столь простой структуре и одному запросу получения меток, работать должно заметно быстрее. Правда, это может быть заметно, когда меток будет мегабайт этак 100-200. Или если базу на сетевой шаре разместить, там тупо число запросов играет против скорости.

Я бы так грубо оценил, что по твоей структуре (из-за её простоты) получать метки (в пределе, при безмерном увеличении их количества) можно примерно вдвое быстрее, чем по моей. Собственно, это и есть один из аргументов на будущее, сделать всё без ORM. Чтобы понять, где предел скорости работы с метками.
Дело в том, что если рассматривать хранение меток в базе данных, обладающей свойством автоматического восстановления после сбоев, имеющей поддержку транзакций и ссылочной целостности (даже если забыть про прочие бонусы типа переносимости базы между любыми платформами), то вряд ли вообще сейчас есть более быстрый способ (формат), чем SQLite3 (я сейчас не говорю про СУБД, там совсем другая кухня, только про локальные способы). Всякие Tokyo/Kyoto сотоварищи если и будут быстрее, то за счёт проигрыша в остальном, да и напильник для их допиливания нужен огого. А по твоей структуре да голыми руками - это будет референсная скорость для локального случая. Собственно, даже хорошо что ты простую структуру взял, лично мне было бы не интересно упрощать модель.
(0016067)
zed   
24-06-2015 05:19   
>надо 6 запросов, чтобы получить видимые метки для экрана
Ну, давай считать: запрос к rtreee индексу за id-шниками меток + количество найденных id умножаем на: запрос за меткой + подзапрос за блобом + подзапрос за картинкой + подзапрос за вьюхой + подзапрос за категорией. Итого: 1 + n*5. А ты говоришь 6 запросов :) Плюс ко всему, я оторвал всякое кэширование, чтобы посмотреть, как оно будет в голом виде. Правда, сам фреймворк что-то кэширует, так что вид не совсем голый.

>Собственно, это и есть один из аргументов на будущее, сделать всё без ORM
Да, вполне. Если будет сильно тормозить.
(0016068)
vasketsov   
24-06-2015 07:59   
>количество найденных id умножаем на
А, значит я не разобрался.

А нельзя ли _средствами_фреймворка_ по полученному списку id:
а) поделить его на куски по N штук (у меня N=127, но можно и больше);
б) выполнять запросы по каждому отдельному куску, а не поштучно, то есть, чтобы в результате в SQL было что-нибудь типа WHERE id in (22,343,4212347)?

А также можно ли слить 5 запросов в 1 прямо в коде или (что правильнее) сделать VIEW поверх таблиц (для чтения), но сделать это так, чтобы результат SELECT-а к VIEW _разобрать_фреймворком_?

Если да, то можно будет обойтись и без написания SQL врукопашную.
(0016069)
zed   
24-06-2015 08:04   
Надо разбираться. Там много чего можно, когда знаешь что хочешь получить, а главное, что такое вообще возможно в SQL. Про "сделать VIEW поверх таблиц" к примеру, я даже не слышал.
(0016071)
vasketsov   
24-06-2015 08:44   
>сделать VIEW поверх таблиц
http://sqlite.org/lang_createview.html
Для SQLite - если без материализации view и только для чтения - это просто псевдоним для всего SELECT, просто перед ним написано create view viewname as ... - и дальше после создания можно не страшный select из кучи таблиц использовать, а просто select * from viewname where ... (все связи скрыты внутри view, а все условия отсечки и поиска натягиваются поверх как на обычную таблицу).
(0016093)
zed   
02-07-2015 13:42   
Сегодня выйдет ночнушка, в которой можно тестировать новые метки. Переключение баз меток сделано в Управлении метками + теперь можно заводить себе несколько баз меток (sml или sqlite) и переключаться между ними на лету: 0002759
(0016122)
zed   
11-07-2015 07:41   
Я вот думаю, может добавить ещё поля с датой создания и модификации метки? И может ещё что добавить?
(0016123)
vasketsov   
11-07-2015 11:37   
>может добавить ещё поля с датой создания и модификации метки?
А ты уверен, что это всем надо?
Именно дату создания метки, которая при импорте будет всегда текущая, и которую поэтому бессмысленно экспортировать?

Вообще подобное можно сделать в виде поля даты и значения default для него (для даты создания) и триггером (для даты изменения), то есть, изменения в структуре данных для подобного логгирования можно сделать вообще без внесения изменений в код программы. Разве что показываться оно не будет, и то в принципе после реализации табличного вида можно сделать, чтобы и неизвестные пользовательские поля отображались.
(0016126)
zed   
11-07-2015 12:07   
Если бы я был уверен, я бы не спрашивал добавить или нет.

По поводу импорта - а что, разве нельзя сделать чтобы и дата переносилась из старой базы, наравне со всеми остальными свойствами?
(0016127)
vasketsov   
11-07-2015 12:15   
>разве нельзя сделать чтобы и дата переносилась из старой базы
Тогда это будет не дата создания метки в базе.
А просто некая дата метки как произвольный атрибут + логика, что его надо устанавливать при создании и менять при изменении, а ещё показывать и фильтроваться/искаться по нему. В этом случае подобная дата будет именно атрибутом метки, и в цепочке действий типа экспорт-импорт-экспорт меняться не будет. А если говорить про дату создания записи, то она атрибутом сущности вообще говоря не является, так как никак с ней не связана, она является атрибутом транзакции загрузки данных.

>Если бы я был уверен, я бы не спрашивал
Я изначально предполагал возможность хранения даты изменения, причём достаточно хитро, там же где описание, пользуясь тем что поля нетипизированы. Но за всё время так об этом никто и не просил, если ничего не путаю, и в итоге это так и не было сделано.
(0016129)
zed   
11-07-2015 12:21   
>А если говорить про дату создания записи
Да кого эта запись вообще волнует? Разговор же про метки и её свойства.
 
Я про дату вспомнил, потому как вроде кто-то когда-то таки просил её и сейчас при создании метки она автоматом залетает в описание. Тогда небыло никакой возможность сохранять её в базе, вот и сделали хоть бы как. А сейчас возможность есть.
(0016131)
vasketsov   
11-07-2015 12:26   
>Разговор же про метки и её свойства
Дата создания метки не является свойством метки, кроме того, она нередактируемая (в противном случае она уже не будет датой создания метки).

Скорее всего, мы друг друга просто неправильно поняли.
И это будет просто обязательный атрибут метки типа "дата", подлежащий экспорту и импорту, и при создании метки в случае отсутствия данных он будет просто заполняться текущей датой. В такой формулировке это не является датой создания или датой изменения, это просто Дата.
(0016132)
zed   
11-07-2015 12:29   
Я вообще предложил 2 даты: создания и последнего изменения. Первая дата не изменяется, а вторая изменяется при каждом редактировании.
(0016134)
vasketsov   
11-07-2015 12:40   
>Первая дата не изменяется, а вторая изменяется
Их можно редактировать руками?
(0016135)
zed   
11-07-2015 12:52   
А нужно? Первоначально, эти даты будут только для отображения, если захочется их ещё и редактировать, то для этого надо будет делать специальный метод.

Предлагаемые даты - прямой аналог даты файла в файловой системе. Стандартный виндозный проводник умеет эти даты показывать, но в WinAPI есть функции и для их изменения, чем и пользуются некоторые программы (TotalCommander, например).
(0016137)
vasketsov   
11-07-2015 13:33   
(edited on: 11-07-2015 13:37)
>прямой аналог даты файла
Понятно.
Я бы не делал.
Слишком узкоспециализированный костыль (ровно два нередактируемых атрибута и только типа даты, ещё и надо захардкодить, как с ними быть).

(0016164)
zed   
15-07-2015 12:00   
Доделал кэширование меток и раз больше никто никаких предложений не вносит и о багах не сообщает, будем считать, что фича работает.
(0016165)
zed   
15-07-2015 19:41   
Кстати, с мелкими фиксами, метки заработали и с PostgreSQL и есть ощущение, что заведутся на большинстве СУБД, с которыми умеет работать ZeosLib. Надо будет добавить настройки для подключения, может кому и пригодится.

И даже почти заработала MongoDB, но там сильно ограниченная поддержка и она не понимает сложных запросов (типа выборки из двух таблиц сразу). Но, теоретически, если специально для неё упростить запросы, то может и завестись.