Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
21.02.2010, 17:06
|
|||
---|---|---|---|
|
|||
пара вопросов: cache_size, journal_mode и блокировка |
|||
#18+
Привет всем! Есть проект построения отчетов, используется БД SQLite. база может быть еденицы - десятки ГБ. Индексы НЕ используются по причине убыстрения вставки в БД. Выборки оч.простые(по одной таблице с order by по нескольким полям), но по объему большие. Как можно обойти следующую ситуацию: - при выполнении долгого одиночного SELECTа база блокируется на запись, т.е. сделать мелкий INSERT/UPDATE из другого потока в другую таблицу в это время невозможно.. SELECT может выполнятся несколько минут, INSERT/UPDATE идет из GUI - соотв-но заставлять пользователя в это время ждать - не вариант.. что можно придумать? если правильно понимаю, можно вынести таблицу по которой идет долгий селект в отд базу(файл) и соотв-но лочится будет только она, в другие таблицы можно будет вставлять/обновлять.. что-то еще? - (мало ли).. какие пути решения проблемы одиночного длинного запроса к таблице и желанием выполнить INSERT из другого потока/процесса? я вот все читаю, читаю.. и не понимаю.. как можно использовать SQLite скажем на веб-серверах, если при большом запросе он может залочить на изменение всю базу, заблокировав любое мелкое изменение всех остальных пользователей.. или считается, что длинных запросов просто не должно быть? Ну и доп. вопросы.. Как и в каких ситуациях влияют на INSERT и SELECT cache_size и journal_mode? ну т.е. из моих тестов, ни то ни то практически не влияет на простой селект и на инсерт.. вот думаю наверно чего-то не знаю. Вообще, конечно, всем хороша SQLite, но эта блокировка на уровне БД.. неужели намного сложней было сделать на уровне таблиц хотяб.. Спасибо за ответы. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
21.02.2010, 23:02
|
|||
---|---|---|---|
|
|||
пара вопросов: cache_size, journal_mode и блокировка |
|||
#18+
Выборка медленная из-за отсутствия индексов. Размер кэша критически влияет на скорость _индексированной_ вставки. Собственно, смотрите тесты, например, здесь: http://geomapx.blogspot.com/2009/11/degradation-of-indexing-speed.html Чтобы не блокировать пользователей, необходимо отказаться от продолжительных выборок на модифицируемой БД. Есть два пути - ускорить выборки или создать slаve-реплику основной базы именно для построения отчетов. Соответствующая утилита есть здесь: http://sqlite.mobigroup.ru/src/wiki?name=sqlite3-rdiff На основе указанной утилиты несложно реализовать инкрементальную репликацию. А если говорить о блокировках в принципе, то под линуксом можно сделать и вовсе без блокировок уровня ФС, заставив ядро "разруливать". Но некоторые [skipped] пользуются другими ОС :-) Так что все претензии перенаправьте к себе ... |
|||
:
Нравится:
Не нравится:
|
|||
|
21.02.2010, 23:46
|
|||
---|---|---|---|
|
|||
пара вопросов: cache_size, journal_mode и блокировка |
|||
#18+
> MBG ... Спасибо за разъяснения.. извините, за ламерские вопросы.. насчет "slаve-реплику основной базы именно для построения отчетов".. я правильно понимаю, что по-сути предлагается сделать копию файла БД и именно с ним работать для SELECT'ов, постоянно синхронизируя ее с master базой, в которую и идут INSERT'ы и UPDATE'ы? какой бы вы посоветовали размер кэша для win и базы до 4ГБ, до 10ГБ, до 100ГБ в случае вкл индексов? насчет journal_mode что-то подскажете? как лучше работать с индексами при необходимости производить массивные INSERT'ы периодически? я пока не разобрался, какие есть варианты.. можно ли отключить обновление индексов перед массивной вставкой и потом обновить индексы сразу по завершению? даст ли это выигрыш? я понимаю, что SELECT убыстрится, но насколько замедлится INSERT? какие камни ожидать при включении индексов? т.к. сейчас индексы не испльзуются - не очень понятно, в каких еще областях применения аукнится включение индексов.. какие подводные камни, если разбить БД на несколько файлов? ну т.е. правильно ли я понимаю, что в принципе так можно реализовать блокировку на уровне таблиц(каждая таблица в своем файле)? есть основная большая таблица.. записи с датой.. если организовать хранение данных скажем за месяц в отдельном файле БД, можно ли создать запрос, который бы делел выборки из заданных файлов? ну т.е. что-то типа select Name, Sum(Incoming), Sum(Outgoing) from T1, T2, T3 where (...) group by Name ? как лучше всего организовать массивную вставку данных из разных потоков в одну таблицу? ну кроме очевидного - выполнять группу инсертов в транзакции в каждом потоке(скажем по 1000 записей).. выносить такую вставку в отдельный поток? делать в каждом потоке INSERT во временную таблицу, а по завершению работы в отдельном потоке средствами SQLite перекидывать данные из временных таблиц в основную? быстро ли это? P.S. как можно выразить вам благодарность за разъяснения? ... |
|||
:
Нравится:
Не нравится:
|
|||
|
22.02.2010, 01:04
|
|||
---|---|---|---|
|
|||
пара вопросов: cache_size, journal_mode и блокировка |
|||
#18+
FILINSQL> MBG ... Спасибо за разъяснения.. извините, за ламерские вопросы.. насчет "slаve-реплику основной базы именно для построения отчетов".. я правильно понимаю, что по-сути предлагается сделать копию файла БД и именно с ним работать для SELECT'ов, постоянно синхронизируя ее с master базой, в которую и идут INSERT'ы и UPDATE'ы? Верно. Только понятие "постоянно" здесь весьма относительно - если отчет строится секунду, зачастую можно и на основной базе его запускать, а если полчаса - то синхронизировать реплику обычно достаточно лишь раз-два в сутки. FILINSQL какой бы вы посоветовали размер кэша для win и базы до 4ГБ, до 10ГБ, до 100ГБ в случае вкл индексов? Вы ссылку смотрели? Не меньше, чем размер вашего индекса. Что касается виндоус, то понятия не имею, ибо последние лет 5 только с дебианом работаю. FILINSQLнасчет journal_mode что-то подскажете? Подскажу - не трогайте. Выигрыш далеко не всегда в реальных приложениях сможете увидеть, а вот угробить базу, тем более под виндоусом, сможете легко. FILINSQL как лучше работать с индексами при необходимости производить массивные INSERT'ы периодически? я пока не разобрался, какие есть варианты.. можно ли отключить обновление индексов перед массивной вставкой и потом обновить индексы сразу по завершению? даст ли это выигрыш? я понимаю, что SELECT убыстрится, но насколько замедлится INSERT? какие камни ожидать при включении индексов? т.к. сейчас индексы не испльзуются - не очень понятно, в каких еще областях применения аукнится включение индексов.. Сгенерите тестовую базу и попробуйте - это лучший путь. Сам так и делаю, для каждого проекта, несмотря на то, что давно и успешно работаю с эскулайт (для других СУБД, разумеется, делаю так же - прежде всего тестирование). FILINSQL какие подводные камни, если разбить БД на несколько файлов? ну т.е. правильно ли я понимаю, что в принципе так можно реализовать блокировку на уровне таблиц(каждая таблица в своем файле)? Так будет сложнее программировать. Но оно окупается удобством администрирования - устаревшие базы легко можно переместить в архив и так же легко вернуть обратно, если потребуется. С монолитной базой проще разрабатывать, но намного сложнее поддерживать. FILINSQL есть основная большая таблица.. записи с датой.. если организовать хранение данных скажем за месяц в отдельном файле БД, можно ли создать запрос, который бы делел выборки из заданных файлов? ну т.е. что-то типа select Name, Sum(Incoming), Sum(Outgoing) from T1, T2, T3 where (...) group by Name ? Можно приаттачить несколько баз и делать выборку, но это неправильно. Лучше выполняйте запрос на каждой БД отдельно, а потом объединяйте результат - так вы ограничитесь фиксированным объемом потребляемой памяти. FILINSQL как лучше всего организовать массивную вставку данных из разных потоков в одну таблицу? ну кроме очевидного - выполнять группу инсертов в транзакции в каждом потоке(скажем по 1000 записей).. выносить такую вставку в отдельный поток? делать в каждом потоке INSERT во временную таблицу, а по завершению работы в отдельном потоке средствами SQLite перекидывать данные из временных таблиц в основную? быстро ли это? Не усложняйте. Есть несколько путей, но у меня в системах с 1000 одновременных пользователей нет никаких проблем с блокировками - эскулайт быстр. Для сбора данных и сохранения их в базу лучше сделать однопоточную программу-демон, которая, к примеру, с 10 атс собирает логи и раз в 5 секунд сохраняет их в БД. Смотрите телефонный биллинг у меня в репозитории, описание - в блоге. FILINSQLP.S. как можно выразить вам благодарность за разъяснения? Легко - сообщить мне что-нибудь новое. Можете протестировать, к примеру, систему поиска http://sqlite.mobigroup.ru/src/wiki?name=poisk или уже названную выше утилиту репликации, или сделать порт на другую ОС/СУБД... Ну, вы поняли. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
|
start [/forum/topic.php?fid=54&tablet=1&tid=2009376]: |
0ms |
get settings: |
11ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
72ms |
get topic data: |
14ms |
get forum data: |
3ms |
get page messages: |
40ms |
get tp. blocked users: |
2ms |
others: | 13ms |
total: | 177ms |
0 / 0 |