Подтвердить что ты не робот

Sqlite3: Отключение индекса первичного ключа при вставке?

У меня есть база данных Sqlite3 с таблицей и основным ключом, состоящим из двух целых чисел, и я пытаюсь вставить в нее много данных (т.е. около 1 ГБ или около того)

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

Итак, я бы хотел как-то временно отключить этот индекс. Мой лучший план до сих пор включал в себя отказ от автоматического индекса первичного ключа, однако кажется, что SQLite ему не нравится и выдает ошибку, если я попытаюсь это сделать.

Мой второй лучший план будет включать приложение, делающее прозрачные копии базы данных на сетевом диске, внося изменения, а затем объединяя их. Обратите внимание, что в отличие от большинства вопросов SQlite/NFS мне не нужен доступ concurrency.

Каким будет правильный способ сделать что-то подобное?

UPDATE:

Я забыл указать флаги, которые уже использую:

PRAGMA synchronous = OFF
PRAGMA journal_mode = OFF
PRAGMA locking_mode = EXCLUSIVE
PRAGMA temp_store = MEMORY

ОБНОВЛЕНИЕ 2: Я фактически вставляю элементы в партии, однако каждая следующая партия медленнее, чем предыдущая (я предполагаю, что это связано с размером индекса). Я пробовал делать партии между кортежами 10k и 50k, каждый из которых представляет собой два целых числа и float.

4b9b3361

Ответ 1

  • Вы не можете удалить встроенный индекс, поскольку он является единственным адресом строки.
  • Объединить 2 целых ключа в один длинный ключ = (key1 < 32) + key2; и сделайте это как ОСНОВНЫЙ КЛЮЧ INTEGER в схеме youd (в этом случае у вас будет только 1 индекс)
  • Установить размер страницы для новой БД не менее 4096
  • Удалить любой дополнительный индекс, кроме первичного
  • Заполните данные в порядке SORTED, чтобы увеличить первичный ключ.
  • Команды повторного использования, не создавайте каждый раз из строки
  • Установите размер кеша страниц на столько же памяти, сколько и осталось (помните, что размер кеша находится в количестве страниц, но не в байтах)
  • Зафиксируйте каждые 50000 элементов.
  • Если у вас есть дополнительные индексы - создайте их только ПОСЛЕ ВСЕХ данных в таблице

Если вы сможете объединить ключ (я думаю, вы используете 32-битный, тогда как sqlite с 64-разрядным, так что это возможно) и заполнять данные в отсортированном порядке. Ставлю, вы заполните свой первый Gb той же производительностью, что и второй, и оба будут достаточно быстрыми.

Ответ 2

Вы делаете INSERT каждого нового как отдельную транзакцию?

Если вы используете BEGIN TRANSACTION и INSERT строки в партиях, я думаю, что индекс будет восстановлен только в конце каждой транзакции.