SQLite SharedCache MultiThread читает

Я занимаюсь разработкой многопоточного приложения базы данных sqlite на виртуальной машине Ubuntu, для которой выделено 4 процессора. Я использую sqlite версии 3.7.13. Я создал тест, чтобы убедиться, что несколько потоков / соединений могут читать из базы данных одновременно.

У меня есть два исполняемых файла. Первый исполняемый файл просто создает базу данных, создает 1 таблицу в этой базе данных, вставляет 50 элементов в эту таблицу и затем закрывает базу данных. Это совсем не предполагает многопоточности и просто предназначено для предоставления базы данных с записями в ней.

Второй исполняемый файл создает несколько потоков для чтения из базы данных и ожидает их завершения и записывает время, необходимое для завершения всех потоков. Каждый поток выполняет следующее: -создание соединения с базой данных с помощью sqlite_open_v2(), чтобы каждый поток имел свое собственное индивидуальное соединение с базой данных, созданной из первого исполняемого файла; -произвести 100000 SELECTS для одной таблицы базы данных (каждый запрос на выбор для одной строки в таблица) - закрыть соединение с базой данных

Когда я запустил этот тест с SQLITE_OPEN_READWRITE, указанным в качестве флагов для sqlite_open_v2 в каждом потоке, я получил следующие результаты для общего времени выполнения всех запросов:

1 темы - 0,65 секунды 2 темы - 0,70 секунды 3 темы - 0,76 секунды 4 темы - 0,91 секунды 5 темы - 1,10 секунды 6 темы - 1,28 секунды 7 темы - 1,57 секунды 8 темы - 1,78 секунды

Эти результаты были ожидаемыми, так как время немного увеличилось (вероятно, из-за переключения контекста между потоками и другими причинами), когда я добавляю потоки, что означает, что чтение в основном выполняется параллельно.

Однако, когда я запустил этот же тест с SQLITE_OPEN_READWRITE | SQLITE_OPEN_SHAREDCACHE для флагов, я получаю следующие результаты:

1 темы - 0,67 секунды 2 темы - 2,43 секунды 3 темы - 4,81 секунды 4 темы - 6,60 секунды 5 темы - 8,03 секунды 6 темы - 9,41 секунды 7 темы - 11,17 секунды 8 темы - 12,79 секунды

Из этих результатов видно, что что-то в режиме общего кэша предотвращает одновременное чтение нескольких данных в базе данных. Я убедился, что действительно разные потоки работают параллельно (чтение потока 4, чтение потока 8, чтение потока 2 и т. Д., А не поток 1 выполняет все свои чтения, поток 2 выполняет все свои чтения, поток 3 выполняет все свои чтения, так далее.). Однако, похоже, что чтения для каждой отдельной транзакции выполняются последовательно или что-то еще замедляет работу базы данных в общем кэше.

Почему я вижу такое большое увеличение времени, когда я добавляю потоки в режиме общего кэша, а не без него? Есть ли способ исправить это и по-прежнему использовать режим общего кэша?

Спасибо за любую помощь. Это высоко ценится.

1 ответ

В настоящее время я могу только сказать, что в shared cache mode каждый поток делает дополнительный read mutex lock() по каждому запросу несколько раз (блокировка в общем кэше, блокировка главной таблицы, блокировка запрошенной таблицы). Конечно, у него есть некоторые накладные расходы.

Чтобы избежать этого вы можете использовать PRAGMA read_uncommitted = true;, но это может привести к противоречивым результатам запроса, если другое соединение с базой данных изменяет таблицу во время чтения, но это также означает, что транзакция чтения, открытая соединением в режиме чтения без фиксации, не может ни блокировать, ни блокироваться каким-либо другим соединением,

(Вы можете предоставить свой код?)

Другие вопросы по тегам