SlideShare a Scribd company logo
Путеводитель SQLite
для разработчика
Спикер:

Василий Сидненко
1
SQLite
«Когда вам хочется что-либо по-настоящему понять, нет лучшего
способа, чем попытаться втолковать это кому-то другому» Д.Адамс
2
Куда бежать, если заказчик
просит «потюнить» базу ?
3
Как это бывает…
• используете SQLite
• протестировали и видите
проблемы
• заказчик видит проблемы и
просит улучшить
• не видит проблем и просит
улучшить
4
Что вначале делает разработчик
5
Что вначале делает разработчик
Нормально же общались…
5
Что пытается делать разработчик
• использовать силу убеждения
• использовать силу переименования
• использовать силу GCD
• использовать силу
6
Что советует делать более опытный
разработчик
использовать силу комбинаторики - pragma , mode …
7
Что в результате делает разработчик
открывает sqlite.org
8
Что мы знаем о SQLite
«Классическая ошибка, которую совершают проектировщики абсолютно надежных
систем, - недооценка изобретательности клинических идиотов» Д.Адамс
9
SQLITE
IS BIG.
REALLY
BIGYou just won’t believe
how vastly, hugely,
mind-bogglingly big it is.
10
Особенности SQLite
• встраиваемая, кроссплатформенная
• открытый доступ, покрытие тестами 100500+
• единый файл, без сервера *
• нет учетных записей (ролей)
• тип данных в столбце - условный
• множественные подключения
• дополнительный функционал *
11
SQLite library
12
SQLite library
12
SQLite library
libsqlite3 всегда указывает на последнюю версию в системе
13
SQLite API - Жизненный цикл
sqlite3_open
Создает конекшн к новой или существующей базе. Возвращает объект sqlite3.
(Конструктор).
14
SQLite API - Жизненный цикл
sqlite3_open
Создает конекшн к новой или существующей базе. Возвращает объект sqlite3.
(Конструктор).
sqlite3_prepare
Преобразовывает(компилирует) стринговый SQL запрос в бинарный объект -
sqlite3_stmt. (Конструктор).
14
SQLite API - Жизненный цикл
sqlite3_open
Создает конекшн к новой или существующей базе. Возвращает объект sqlite3.
(Конструктор).
sqlite3_prepare
Преобразовывает(компилирует) стринговый SQL запрос в бинарный объект -
sqlite3_stmt. (Конструктор).
sqlite3_bind Сохраняет данные в параметры выражения (Биндинг)
14
SQLite API - Жизненный цикл
sqlite3_open
Создает конекшн к новой или существующей базе. Возвращает объект sqlite3.
(Конструктор).
sqlite3_prepare
Преобразовывает(компилирует) стринговый SQL запрос в бинарный объект -
sqlite3_stmt. (Конструктор).
sqlite3_bind Сохраняет данные в параметры выражения (Биндинг)
sqlite3_step
Выполняет созданное выражение (sqlite3_stmt),
возвращает указатель на первую (и последующие при вызове) строки результата
14
SQLite API - Жизненный цикл
sqlite3_open
Создает конекшн к новой или существующей базе. Возвращает объект sqlite3.
(Конструктор).
sqlite3_prepare
Преобразовывает(компилирует) стринговый SQL запрос в бинарный объект -
sqlite3_stmt. (Конструктор).
sqlite3_bind Сохраняет данные в параметры выражения (Биндинг)
sqlite3_step
Выполняет созданное выражение (sqlite3_stmt),
возвращает указатель на первую (и последующие при вызове) строки результата
sqlite3_column
Возвращает значение столбца в выполненном выражении. «Абстрактный».
Используются - sqlite3_column_text(), sqlite3_column_int() …
14
SQLite API - Жизненный цикл
sqlite3_open
Создает конекшн к новой или существующей базе. Возвращает объект sqlite3.
(Конструктор).
sqlite3_prepare
Преобразовывает(компилирует) стринговый SQL запрос в бинарный объект -
sqlite3_stmt. (Конструктор).
sqlite3_bind Сохраняет данные в параметры выражения (Биндинг)
sqlite3_step
Выполняет созданное выражение (sqlite3_stmt),
возвращает указатель на первую (и последующие при вызове) строки результата
sqlite3_column
Возвращает значение столбца в выполненном выражении. «Абстрактный».
Используются - sqlite3_column_text(), sqlite3_column_int() …
sqlite3_finalize Деструктор выражения (sqlite3_stmt)
14
SQLite API - Жизненный цикл
sqlite3_open
Создает конекшн к новой или существующей базе. Возвращает объект sqlite3.
(Конструктор).
sqlite3_prepare
Преобразовывает(компилирует) стринговый SQL запрос в бинарный объект -
sqlite3_stmt. (Конструктор).
sqlite3_bind Сохраняет данные в параметры выражения (Биндинг)
sqlite3_step
Выполняет созданное выражение (sqlite3_stmt),
возвращает указатель на первую (и последующие при вызове) строки результата
sqlite3_column
Возвращает значение столбца в выполненном выражении. «Абстрактный».
Используются - sqlite3_column_text(), sqlite3_column_int() …
sqlite3_finalize Деструктор выражения (sqlite3_stmt)
sqlite3_close Закрывает соединение. Деструктор (sqlite3).
14
SQLite API - Настройки
sqlite3_config
• настройка выделения памяти
• логирования
• кеш
• threading model
• sqlite3_db_config - для конкретного соединения
15
SQLite API - Настройки
sqlite3_config
• настройка выделения памяти
• логирования
• кеш
• threading model
• sqlite3_db_config - для конкретного соединения
pragma
• изменение самой библиотеки или запросов к не табличным
данным
• нет обратной совместимости
• нет ошибок
• разный эффект на разных стадиях жизненного цикла
• можно применять к конкретному соединению
15
Amalgamation
16
Amalgamation
• SQLite проект содержит более 100 отдельных
файлов
• Amalgamation - объединение всего, что нужно в
одном .c файле
• Содержит более 180000 строк кода и весит
более 6 MB
• Предназначен для кастомной сборки SQLite
17
SQLite Hand Made
18
Command-Line Shell - sqlite3
19
SQLite и многопоточность
// Что если я тебе скажу
/ * что с sqlite можно работать
из разных потоков */
20
Threading mode - режимы
Single-Thread
Не защищенный режим. Не используются никакие средства
синхронизации потоков. Работать более чем в одном потоке
не безопасно!
21
Threading mode - режимы
Single-Thread
Не защищенный режим. Не используются никакие средства
синхронизации потоков. Работать более чем в одном потоке
не безопасно!
Multi-Thread
Нельзя использовать несколько потоков для одного
соединения, но можно использовать отдельный поток для
каждого соединения.
21
Threading mode - режимы
Single-Thread
Не защищенный режим. Не используются никакие средства
синхронизации потоков. Работать более чем в одном потоке
не безопасно!
Multi-Thread
Нельзя использовать несколько потоков для одного
соединения, но можно использовать отдельный поток для
каждого соединения.
Serialized (default *)
Безопасный режим, но все запросы выполняются
последовательно.
21
Threading mode - настройка
Compile-time
Компиляция SQLite
compile-time - параметр
SQLITE_THREADSAFE
или
-DSQLITE_THREADSAFE=1
-DSQLITE_THREADSAFE=2
22
Threading mode - настройка
Compile-time Start-time
Компиляция SQLite
compile-time - параметр
SQLITE_THREADSAFE
или
-DSQLITE_THREADSAFE=1
-DSQLITE_THREADSAFE=2
Инициализация SQLite
sqlite3_config() - параметр
SQLITE_CONFIG_SINGLETHREAD
SQLITE_CONFIG_MULTITHREAD
SQLITE_CONFIG_SERIALIZED
22
Threading mode - настройка
Compile-time Start-time Run-time
Компиляция SQLite
compile-time - параметр
SQLITE_THREADSAFE
или
-DSQLITE_THREADSAFE=1
-DSQLITE_THREADSAFE=2
Инициализация SQLite
sqlite3_config() - параметр
SQLITE_CONFIG_SINGLETHREAD
SQLITE_CONFIG_MULTITHREAD
SQLITE_CONFIG_SERIALIZED
Открытие соединения
sqlite3_open() - параметр
SQLITE_OPEN_NOMUTEX
SQLITE_OPEN_FULLMUTEX
22
Потокобезопасность
sqlite3_threadsafe()
23
Потокобезопасность
sqlite3_threadsafe()
Показывает параметр компиляции -
DSQLITE_THREADSAFE,
а не реальный режим доступа!
24
Многопоточность
25
Threading mode
26
Threading mode
По умолчанию SQLite не в
Serialized режиме!
26
Threading mode
По умолчанию SQLite не в
Serialized режиме!
26
Threading mode
По умолчанию SQLite не в
Serialized режиме!
Устанавливаем Serialized
26
Многопоточность
Для управления режимом - просто включите его
Только на этапе инициализации SQLite можно установить любой режим
Хороший тон - принудительная инициализация и выключение SQLite
sqlite3_initialize();
sqlite3_shutdown();
27
Тест 1 - Единое Соединение
Single-Thread NO
Multi-Thread NO
Serialized YES
28
Тест 1 - Единое Соединение
Single-Thread NO
Multi-Thread NO
Serialized YES
ConnectionSQLite
Thread 1
Thread 2
28
Тест 2 - Отдельные соединения
Single-Thread NO
Multi-Thread YES
Serialized YES
29
Тест 2 - Отдельные соединения
Thread 1
Connection 1
SQLite
Thread 2
Connection 2
Single-Thread NO
Multi-Thread YES
Serialized YES
29
Многопоточный доступ
Connection
Read-
Write
Thread Serialized Multi-Thread Single-Thread (!)
Single
R
1 OK
Crash Crash
2 OK
R-W
1 OK-OK
Crash Crash
2 OK-OK
Multi
R
1 OK OK OK (!)
2 OK OK OK (!)
R-W
1 OK-OK (OK-BUSY) OK-OK (OK-BUSY) OK-OK (OK-BUSY) (!)
2 OK-BUSY OK-BUSY OK-BUSY (!)
30
SQLite File Locking (classic*)
• механизм управления блокировкой и конкурентным доступом
• является главным инструментом реализации ACID
• напрямую связан с понятием транзакции
• устанавливается с помощью pragma locking_mode
SQLITE_BUSY - это все о нем
31
File Locking - modes
NORMAL
(по умолчанию)
sqlite3_exec(connection, "PRAGMA locking_mode=NORMAL", NULL,
NULL, NULL);
SQLite будет будет устанавливать (lock) и сбрасывать блокировку (unlock)
для каждой транзакции.
EXCLUSIVE
sqlite3_exec(connection, "PRAGMA locking_mode=EXCLUSIVE", NULL,
NULL, NULL);
SQLite заблокирует базу на все время жизни соединения.
Для временых («») и в памяти («:memory:») баз является единственно возможным
32
File Locking - обработка
sqlite3_busy_timeout
(connection, 1000)
SQLite будет пытаться получить доступ к ресурсу
(после SQLITE_BUSY) в течении интервала (mc)
sqlite3_busy_handler
(connection, &sqliteCallback,
NULL)
Определяемый каллбек вызывается при получении
SQLITE_BUSY.
Если каллбек возвращает 0, клиенту перенаправляется
SQLITE_BUSY, иначе SQLite снова пытается получить
доступ
33
Используем locking handlers
Connection
Read-
Write
Thread Serialized Multi-Thread Single-Thread (!)
Single
R
1 OK
Crash Crash
2 OK
R-W
1 OK-OK
Crash Crash
2 OK-OK
Multi
R
1 OK OK OK (!)
2 OK OK OK (!)
R-W
1 OK-OK OK-OK OK-OK (!)
2 OK-OK OK-OK OK-OK (OK-BUSY) (!)
34
Shared-Cache
Thread 1
SQLite
Connection 1
Normal
Locking
Mode
35
Shared-Cache
Thread 1
SQLite
Connection 1
Thread 2
Connection 2 Connection 3
Shared
Cache
Normal
Locking
Mode
Shared-
Cache
Locking
Mode
35
SQLite Shared-Cache Mode
sqlite3_enable_shared_cache() *
*кроме Mac OSX 10.7 и iOS 5
Установка режима для ВСЕХ соединений базы
Mac OSX 10.7 и iOS 5
Параметр открытия соединения
SQLITE_OPEN_SHAREDCACHE - добавляет КОНКРЕТНОЕ
соединение в шаред кеш
Позволяет существенно уменьшить потребление
памяти для I/O операций
Отключен по умолчанию
Добавляет новую модель блокировки - «shared cache
locking model»
36
Shared-Cache Locking Model
Transaction Level
Locking
Запись - только ОДНА транзакция в один момент времени
Чтение - не ограничено
Table Level
Locking
Запись - только ОДИН (write-lock) для таблицы в один момент времени
Чтение - (read-lock) не ограничено
Serialized mode
(по умолчанию)
Данные синхронизированы с записью в таблицу. Чтение
вернет либо данные ДО записи, либо УЖЕ ПОСЛЕ записи.
Read-Uncommitted
mode
Данные НЕ синхронизированы с записью. Возможно
получение не консистентных данных !
PRAGMA read_uncommitted = <boolean>;
Schema Level
Locking
Поддерживает Table Level Locking с ограничениями *
37
Shared cache
Connection
Read-
Write
Serialized Multi-Thread Single-Thread (!)
Multi
R
OK OK
SQLITE_CORRUPT
CRASH
OK OK
R-W
OK-OK OK-OK
OK-OK OK-OK
38
Транзакция
• Атомарность (atomicity)
39
Транзакция
• Атомарность (atomicity)
• Согласованность (consistency)
39
Транзакция
• Атомарность (atomicity)
• Согласованность (consistency)
• Изолированность (isolation)
39
Транзакция
• Атомарность (atomicity)
• Согласованность (consistency)
• Изолированность (isolation)
• Долговечность (durability)
ACID
39
Транзакция
Главный инструмент реализации - журнал
Создается
Явно
BEGIN … COMMIT
Не явно
40
Атомарный комит
• Во время транзакции изменения применяются полностью, либо
совсем не происходят
41
Атомарный комит
• Во время транзакции изменения применяются полностью, либо
совсем не происходят
• Rollback mode - стандартный режим реализации с временным
журналом
41
Атомарный комит
• Во время транзакции изменения применяются полностью, либо
совсем не происходят
• Rollback mode - стандартный режим реализации с временным
журналом
• WAL (write-ahead log) mode - новый режим с постоянным
журналом
41
Атомарный комит
1 Исходное состояние -
1
42
Атомарный комит
1 Исходное состояние -
2 Запрос на чтение. BEGIN Shared Lock
1
2
42
Атомарный комит
1 Исходное состояние -
2 Запрос на чтение. BEGIN Shared Lock
3 Чтение
Reserved Lock 1
2
3
42
Атомарный комит
1 Исходное состояние -
2 Запрос на чтение. BEGIN Shared Lock
3 Чтение
Reserved Lock4 Создание журнала и запись в него изменений 1
2
34
42
Атомарный комит
1 Исходное состояние -
2 Запрос на чтение. BEGIN Shared Lock
3 Чтение
Reserved Lock4 Создание журнала и запись в него изменений
5 Запись журнала на диск.
1
2
345
42
Атомарный комит
1 Исходное состояние -
2 Запрос на чтение. BEGIN Shared Lock
3 Чтение
Reserved Lock4 Создание журнала и запись в него изменений
5 Запись журнала на диск.
6 Запись изменений в базу(в памяти)
Exclusive lock
1
2
3456
42
Атомарный комит
1 Исходное состояние -
2 Запрос на чтение. BEGIN Shared Lock
3 Чтение
Reserved Lock4 Создание журнала и запись в него изменений
5 Запись журнала на диск.
6 Запись изменений в базу(в памяти)
Exclusive lock7 Запись базы на диск
1
2
3456
7
42
Атомарный комит
1 Исходное состояние -
2 Запрос на чтение. BEGIN Shared Lock
3 Чтение
Reserved Lock4 Создание журнала и запись в него изменений
5 Запись журнала на диск.
6 Запись изменений в базу(в памяти)
Exclusive lock7 Запись базы на диск
8 Удаление журнала. COMMIT
1
2
3456
7
8
42
Атомарный комит
1 Исходное состояние -
2 Запрос на чтение. BEGIN Shared Lock
3 Чтение
Reserved Lock4 Создание журнала и запись в него изменений
5 Запись журнала на диск.
6 Запись изменений в базу(в памяти)
Exclusive lock7 Запись базы на диск
8 Удаление журнала. COMMIT
9 Исходное состояние с изменениями -
1
2
3456
7
89
42
Rollback
Когда что-то пошло не так
43
Rollback
7 Hot journal Shared lock
7
44
Rollback
7 Hot journal Shared lock
8 Запись не выполненных изменений
Exclusive lock
7
8
44
Rollback
7 Hot journal Shared lock
8 Запись не выполненных изменений
Exclusive lock
9 Удаление журнала
7
8
9
44
Rollback
7 Hot journal Shared lock
8 Запись не выполненных изменений
Exclusive lock
9 Удаление журнала
10 Исходное состояние с изменениями -
7
8
9
10
44
Rollback
Вызов ROLLBACK во время транзакции просто удаляет журнал
45
Синхронизация транзакции
OFF
SQLite считает данные записанными сразу после передачи ОС, то
есть целостность данных зависит от работы системы.
46
Синхронизация транзакции
OFF
SQLite считает данные записанными сразу после передачи ОС, то
есть целостность данных зависит от работы системы.
NORMAL
Компромиссный режим при котором возможна маленькая
вероятность потери данных при креше системы
46
Синхронизация транзакции
OFF
SQLite считает данные записанными сразу после передачи ОС, то
есть целостность данных зависит от работы системы.
NORMAL
Компромиссный режим при котором возможна маленькая
вероятность потери данных при креше системы
FULL
(по умолчанию)
Гарантия целостности данных в любых ситуациях.
46
Синхронизация транзакции
OFF
SQLite считает данные записанными сразу после передачи ОС, то
есть целостность данных зависит от работы системы.
NORMAL
Компромиссный режим при котором возможна маленькая
вероятность потери данных при креше системы
FULL
(по умолчанию)
Гарантия целостности данных в любых ситуациях.
EXTRA Гарантия гарантии целостности в любых любых ситуациях
46
Режимы журнала
DELETE
(по умолчанию)
Журнал удаляется после транзакции
47
Режимы журнала
DELETE
(по умолчанию)
Журнал удаляется после транзакции
TRANCATE Журнал обрезается до нуля (может работать быстрее чем создание/удаление)
47
Режимы журнала
DELETE
(по умолчанию)
Журнал удаляется после транзакции
TRANCATE Журнал обрезается до нуля (может работать быстрее чем создание/удаление)
PERSIST Журнал заполняется нулями, размер не изменяется
47
Режимы журнала
DELETE
(по умолчанию)
Журнал удаляется после транзакции
TRANCATE Журнал обрезается до нуля (может работать быстрее чем создание/удаление)
PERSIST Журнал заполняется нулями, размер не изменяется
WAL
Постоянный журнал. Работает быстрее. Предпочтительный. Запись и чтение не
блокируют друг друга*
47
Режимы журнала
DELETE
(по умолчанию)
Журнал удаляется после транзакции
TRANCATE Журнал обрезается до нуля (может работать быстрее чем создание/удаление)
PERSIST Журнал заполняется нулями, размер не изменяется
WAL
Постоянный журнал. Работает быстрее. Предпочтительный. Запись и чтение не
блокируют друг друга*
MEMORY Журнал в оперативной памяти. Быстро но не надежно
47
Режимы журнала
DELETE
(по умолчанию)
Журнал удаляется после транзакции
TRANCATE Журнал обрезается до нуля (может работать быстрее чем создание/удаление)
PERSIST Журнал заполняется нулями, размер не изменяется
WAL
Постоянный журнал. Работает быстрее. Предпочтительный. Запись и чтение не
блокируют друг друга*
MEMORY Журнал в оперативной памяти. Быстро но не надежно
OFF Без журнала - без транзакций
47
WAL (Write-Ahead Logging)
Преимущества
Существенно быстрее
Писатели не блокируют читателей
Операции I/O более упорядочены
Меньше обращается к диску (fsync())
48
WAL (Write-Ahead Logging)
Преимущества
Существенно быстрее
Писатели не блокируют читателей
Операции I/O более упорядочены
Меньше обращается к диску (fsync())
Недостатки
Не работает с распределенным доступом
(по сети)
Невозможно изменить размер страницы
( page_size )
Невозможно создать соединение только для
чтения
Может быть чуть медленней (1-2%), если в
основном происходит чтение
База имеет постоянные дополнительные файлы -
«-shm», «-wal»
Дополнительная операция - чекпоинт
(checkpoint)
48
WAL
Commit Checkpoint
Означает что изменения сохранились в журнал
Означает перенос изменений из журнала в файл
базы
Изменения попадают в файл базы только после
чекпоинта (checkpoint)
Автоматически - по значению порога журнала -
1000 страниц (~4Mb)
SQLITE_DEFAULT_WAL_AUTOCHECKPOINT
Порог авточекпоинта может быть изменен
PRAGMA wal_autocheckpoint=N;
Авточекпоинт может быть отключен
(PRAGMA wal_autocheckpoint=0),
тогда он должен выполнятся вручную
sqlite3_wal_checkpoint_v2()
49
1 Исходное состояние
1
db
wal
shm
Writer
w0
Reader
wem0
wem - writer end-markrem - reader end-mark w - comit-reader -writer
WAL - R/W
50
1 Исходное состояние
2
Получение валидного комита (wem0) ,
сохранение своего (rem1)
1
db
wal
shm
Writer
w0
Reader
wem0
2
db
wal
shm
Writer
w0
rem1
Reader
wem0
wem - writer end-markrem - reader end-mark w - comit-reader -writer
WAL - R/W
50
1 Исходное состояние
2
Получение валидного комита (wem0) ,
сохранение своего (rem1)
3
Чтение от rem1 журнала и по всему файлу
базы
1
db
wal
shm
Writer
w0
Reader
wem0
2
db
wal
shm
Writer
w0
rem1
Reader
wem0
3
db
wal
shm
Writer
w0
rem1
Reader
wem0
wem - writer end-markrem - reader end-mark w - comit-reader -writer
WAL - R/W
50
1 Исходное состояние
2
Получение валидного комита (wem0) ,
сохранение своего (rem1)
3
Чтение от rem1 журнала и по всему файлу
базы
4 Удаление своего rem1
1
db
wal
shm
Writer
w0
Reader
wem0
2
db
wal
shm
Writer
w0
rem1
Reader
wem0
3
db
wal
shm
Writer
w0
rem1
Reader
wem0
4
db
wal
shm
Writer
w0
rem1
Reader
wem0
wem - writer end-markrem - reader end-mark w - comit-reader -writer
WAL - R/W
50
1 Исходное состояние
2
Получение валидного комита (wem0) ,
сохранение своего (rem1)
3
Чтение от rem1 журнала и по всему файлу
базы
4 Удаление своего rem1
5 Получение валидного комита (wem0)
1
db
wal
shm
Writer
w0
Reader
wem0
2
db
wal
shm
Writer
w0
rem1
Reader
wem0
3
db
wal
shm
Writer
w0
rem1
Reader
wem0
4
db
wal
shm
Writer
w0
rem1
Reader
wem0
5
db
wal
shm
Writer
w0
Reader
wem0
wem - writer end-markrem - reader end-mark w - comit-reader -writer
WAL - R/W
50
1 Исходное состояние
2
Получение валидного комита (wem0) ,
сохранение своего (rem1)
3
Чтение от rem1 журнала и по всему файлу
базы
4 Удаление своего rem1
5 Получение валидного комита (wem0)
6 Запись изменений в журнал после w0
1
db
wal
shm
Writer
w0
Reader
wem0
2
db
wal
shm
Writer
w0
rem1
Reader
wem0
3
db
wal
shm
Writer
w0
rem1
Reader
wem0
4
db
wal
shm
Writer
w0
rem1
Reader
wem0
5
db
wal
shm
Writer
w0
Reader
wem0
6
db
wal
shm
Writer
w0
Reader
wem0
w1
wem - writer end-markrem - reader end-mark w - comit-reader -writer
WAL - R/W
50
1 Исходное состояние
2
Получение валидного комита (wem0) ,
сохранение своего (rem1)
3
Чтение от rem1 журнала и по всему файлу
базы
4 Удаление своего rem1
5 Получение валидного комита (wem0)
6 Запись изменений в журнал после w0
7 Запись журнала w1 на диск
1
db
wal
shm
Writer
w0
Reader
wem0
2
db
wal
shm
Writer
w0
rem1
Reader
wem0
3
db
wal
shm
Writer
w0
rem1
Reader
wem0
4
db
wal
shm
Writer
w0
rem1
Reader
wem0
5
db
wal
shm
Writer
w0
Reader
wem0
6
db
wal
shm
Writer
w0
Reader
wem0
w1
7
db
wal
shm
Writer
w0
Reader
wem0
w1
wal disk
w1
wem - writer end-markrem - reader end-mark w - comit-reader -writer
WAL - R/W
50
1 Исходное состояние
2
Получение валидного комита (wem0) ,
сохранение своего (rem1)
3
Чтение от rem1 журнала и по всему файлу
базы
4 Удаление своего rem1
5 Получение валидного комита (wem0)
6 Запись изменений в журнал после w0
7 Запись журнала w1 на диск
8
Обновление в shm последнего комита
(wem1). COMMIT
1
db
wal
shm
Writer
w0
Reader
wem0
2
db
wal
shm
Writer
w0
rem1
Reader
wem0
3
db
wal
shm
Writer
w0
rem1
Reader
wem0
4
db
wal
shm
Writer
w0
rem1
Reader
wem0
5
db
wal
shm
Writer
w0
Reader
wem0
6
db
wal
shm
Writer
w0
Reader
wem0
w1
7
db
wal
shm
Writer
w0
Reader
wem0
w1
wal disk
w1
8
db
wal
shm
Writer
w0
Reader
wem0
w1
wem1
wem - writer end-markrem - reader end-mark w - comit-reader -writer
WAL - R/W
50
1 Исходное состояние
2
Получение валидного комита (wem0) ,
сохранение своего (rem1)
3
Чтение от rem1 журнала и по всему файлу
базы
4 Удаление своего rem1
5 Получение валидного комита (wem0)
6 Запись изменений в журнал после w0
7 Запись журнала w1 на диск
8
Обновление в shm последнего комита
(wem1). COMMIT
9 Исходное состояние с изменениями
1
db
wal
shm
Writer
w0
Reader
wem0
2
db
wal
shm
Writer
w0
rem1
Reader
wem0
3
db
wal
shm
Writer
w0
rem1
Reader
wem0
4
db
wal
shm
Writer
w0
rem1
Reader
wem0
5
db
wal
shm
Writer
w0
Reader
wem0
6
db
wal
shm
Writer
w0
Reader
wem0
w1
7
db
wal
shm
Writer
w0
Reader
wem0
w1
wal disk
w1
8
db
wal
shm
Writer
w0
Reader
wem0
w1
wem1
9
db
wal
shm
Writer
w0
Reader
wem1
w1
wem - writer end-markrem - reader end-mark w - comit-reader -writer
WAL - R/W
50
1
Условие чекпоинта выполнено
(сразу после COMMIT или вручную)
1
db
wal
shm
Writer
w0
Reader
wem1
w1
rem2
}CL
WAL - checkpoint
wem - writer end-markrem - reader end-mark w - comit-reader -writer -checkpoint CL - checkpoint level51
1
Условие чекпоинта выполнено
(сразу после COMMIT или вручную)
2
Перенос страниц из конца журнала в базу до
первого rem
1
db
wal
shm
Writer
w0
Reader
wem1
w1
rem2
}CL
2
db
wal
shm
Check
point
w0
Reader
wem1
w1
w1
rem2
WAL - checkpoint
wem - writer end-markrem - reader end-mark w - comit-reader -writer -checkpoint CL - checkpoint level51
1
Условие чекпоинта выполнено
(сразу после COMMIT или вручную)
2
Перенос страниц из конца журнала в базу до
первого rem
3 Запись файла базы на диск
1
db
wal
shm
Writer
w0
Reader
wem1
w1
rem2
}CL
2
db
wal
shm
Check
point
w0
Reader
wem1
w1
w1
rem2
3
db
wal
shm
Check
point
w0
Reader
wem1
w1
w1
rem2
db disk
w1
WAL - checkpoint
wem - writer end-markrem - reader end-mark w - comit-reader -writer -checkpoint CL - checkpoint level51
1
Условие чекпоинта выполнено
(сразу после COMMIT или вручную)
2
Перенос страниц из конца журнала в базу до
первого rem
3 Запись файла базы на диск
4
Обновление в shm последнего комита (wem1).
COMMIT
1
db
wal
shm
Writer
w0
Reader
wem1
w1
rem2
}CL
2
db
wal
shm
Check
point
w0
Reader
wem1
w1
w1
rem2
3
db
wal
shm
Check
point
w0
Reader
wem1
w1
w1
rem2
db disk
w1
4
db
wal
shm
Check
point
w0
Reader
wem1
w1
w1
rem2
wem0
WAL - checkpoint
wem - writer end-markrem - reader end-mark w - comit-reader -writer -checkpoint CL - checkpoint level51
1
Условие чекпоинта выполнено
(сразу после COMMIT или вручную)
2
Перенос страниц из конца журнала в базу до
первого rem
3 Запись файла базы на диск
4
Обновление в shm последнего комита (wem1).
COMMIT
5 Исходное состояние с изменениями
1
db
wal
shm
Writer
w0
Reader
wem1
w1
rem2
}CL
2
db
wal
shm
Check
point
w0
Reader
wem1
w1
w1
rem2
3
db
wal
shm
Check
point
w0
Reader
wem1
w1
w1
rem2
db disk
w1
4
db
wal
shm
Check
point
w0
Reader
wem1
w1
w1
rem2
wem0
5
db
wal
shm
Check
point
w0
Reader
wem0
w1
rem2
WAL - checkpoint
wem - writer end-markrem - reader end-mark w - comit-reader -writer -checkpoint CL - checkpoint level51
WAL
52
WAL
Для ускорения чтения
как можно меньший журнал
(поиск end-mark зависит от размера) - то есть
делать чекпоинты
как можно чаще -
в идеале каждый комит
53
WAL
Для ускорения чтения
как можно меньший журнал
(поиск end-mark зависит от размера) - то есть
делать чекпоинты
как можно чаще -
в идеале каждый комит
Для ускорения записи
как можно дольше
не делать чекпоинт
(из-за дополнительного времени на перенос в
базу и двойной записи на диск)
53
WAL
1 Создаем базу SQLite
54
WAL
1 Создаем базу SQLite
2 Меняем режим на WAL
54
WAL
1 Создаем базу SQLite
2 Меняем режим на WAL
3 Журнал пустой
54
WAL
1 Создаем базу SQLite
2 Меняем режим на WAL
3 Журнал пустой
4 Вносим изменения
54
WAL
1 Создаем базу SQLite
2 Меняем режим на WAL
3 Журнал пустой
4 Вносим изменения
5 Журнал активен (данные в
журнале, а не в файле базы)
54
Индексы и
планировщик запросов
SQLite Query Planner -
ИИ, который выбирает наилучший
способ выполнить запрос, и индексы
являются его главным инструментом
55
Поиск (SELECT)
Полное
сканирование
(Full Table Scan)
Полный перебор
56
Поиск (SELECT)
Полное
сканирование
(Full Table Scan)
Полный перебор
Поиск по RowID
(Lookup By Rowid)
Бинарный поиск по таблице
56
Поиск (SELECT)
Полное
сканирование
(Full Table Scan)
Полный перебор
Поиск по RowID
(Lookup By Rowid)
Бинарный поиск по таблице
Поиск по индексу
(Lookup By Index)
Бинарный поиск по индексу
+ бинарный поиск по
таблице
56
Поиск (SELECT)
Полное
сканирование
(Full Table Scan)
Полный перебор
Поиск по RowID
(Lookup By Rowid)
Бинарный поиск по таблице
Поиск по индексу
(Lookup By Index)
Бинарный поиск по индексу
+ бинарный поиск по
таблице
Покрытие индекса
(Covering Indices)
Бинарный поиск по индексу
56
Сортировка (ORDER BY)
Сортировка по
значению
«Сложная» сортировка
57
Сортировка (ORDER BY)
Сортировка по
значению
«Сложная» сортировка
Сортировка по
RowID
Просто вывод
57
Сортировка (ORDER BY)
Сортировка по
значению
«Сложная» сортировка
Сортировка по
RowID
Просто вывод
Сортировка по
индексу
«Простая» сортировка
57
Сортировка (ORDER BY)
Сортировка по
значению
«Сложная» сортировка
Сортировка по
RowID
Просто вывод
Сортировка по
индексу
«Простая» сортировка
Сортировка по
покрытому индексу Просто вывод
57
Индексы
Индекс - упорядоченная таблица, связанная с оригинальной
58
Индексы
• Замедляют операции изменений за
счет переиндексации (REINDEX)
Индекс - упорядоченная таблица, связанная с оригинальной
58
Индексы
• Замедляют операции изменений за
счет переиндексации (REINDEX)
• Могут быть частичными (Partial) - для
определенных строк
Индекс - упорядоченная таблица, связанная с оригинальной
58
Индексы
• Замедляют операции изменений за
счет переиндексации (REINDEX)
• Могут быть частичными (Partial) - для
определенных строк
• Могут быть уникальными (UNIQUE)
Индекс - упорядоченная таблица, связанная с оригинальной
58
Индексы
• Замедляют операции изменений за
счет переиндексации (REINDEX)
• Могут быть частичными (Partial) - для
определенных строк
• Могут быть уникальными (UNIQUE)
• Индекс по умолчанию - RowID
Индекс - упорядоченная таблица, связанная с оригинальной
58
Индексы
Не нужны, когда
Мало данных
Изменения в таблице происходят
намного чаще чем выборки
• Замедляют операции изменений за
счет переиндексации (REINDEX)
• Могут быть частичными (Partial) - для
определенных строк
• Могут быть уникальными (UNIQUE)
• Индекс по умолчанию - RowID
Индекс - упорядоченная таблица, связанная с оригинальной
58
Индексы
Не нужны, когда
Мало данных
Изменения в таблице происходят
намного чаще чем выборки
Плохо в качестве индекса, когда
Значения поля часто NULL
Значения поля часто меняется
• Замедляют операции изменений за
счет переиндексации (REINDEX)
• Могут быть частичными (Partial) - для
определенных строк
• Могут быть уникальными (UNIQUE)
• Индекс по умолчанию - RowID
Индекс - упорядоченная таблица, связанная с оригинальной
58
Таблицы без ROWID
МОГУТ повысить быстродействие и уменьшить размер
59
Таблицы без ROWID
• Если используются составные первичные
ключи
• Если первичный ключ - Integer (просто
дупликация)
• Если не хранятся большие строки или BLOB
• В целом - если размер таблиц - небольшой
( < 1/20 страницы )
МОГУТ повысить быстродействие и уменьшить размер
59
Таблицы без ROWID
• Обязаны иметь первичный
ключ!
• Автоинкремент не работает
• Первичный ключ не может
быть NULL
• Если используются составные первичные
ключи
• Если первичный ключ - Integer (просто
дупликация)
• Если не хранятся большие строки или BLOB
• В целом - если размер таблиц - небольшой
( < 1/20 страницы )
sqlite3_analyzer
МОГУТ повысить быстродействие и уменьшить размер
59
Full Text Search
60
Расширения (модули), позволяющие выполнять эффективный
полнотекстовый поиск, путем создания спец виртуальных таблиц
Full Text Search
60
Расширения (модули), позволяющие выполнять эффективный
полнотекстовый поиск, путем создания спец виртуальных таблиц
FTS3, FTS4 подключены по молчанию
Full Text Search
60
Расширения (модули), позволяющие выполнять эффективный
полнотекстовый поиск, путем создания спец виртуальных таблиц
FTS3, FTS4 подключены по молчанию
FTS4 более оптимизирована и производительна, но занимает больше
места в памяти
Full Text Search
60
Расширения (модули), позволяющие выполнять эффективный
полнотекстовый поиск, путем создания спец виртуальных таблиц
FTS3, FTS4 подключены по молчанию
FTS4 более оптимизирована и производительна, но занимает больше
места в памяти
При поиске для сравнения после WHERE используется терма MATCH
FTS - Tokenizer
Набор правил для выборки
61
FTS - Tokenizer
Набор правил для выборки
simple
(по умолчанию)
Добавляет регистронезависимость
porter Алгоритм стемминга Портера (упр. - поиск по корню слова)
icu Учитывает локаль (пр. - icu uk_UA)
кастомный Реализуется используя интерфейс fts3_tokenizer.h
stop-word
Популярный токенайзер для исключения слов из выборки
(FMStopWordTokenizer)
61
FTS - использование
// 1 столбец - «content»
CREATE VIRTUAL TABLE data USING fts4();
// 2 кастомных столбца и токенайзер porter
CREATE VIRTUAL TABLE data USING fts4(title, keywords, tokenize=porter);
// вирт таблица просто ссылается на реальную
CREATE VIRTUAL TABLE IF NOT EXISTS fdocs
USING fts4(content="docs", name, tokenize=simple)
// запрос
SELECT name, composer FROM fdocs WHERE fdocs MATCH ‘nix’»
// перестройка fts таблицы (триггеров нет)
INSERT INTO fdocs(fdocs) VALUES('rebuild');
// оптимизация*
INSERT INTO fdocs(fdocs) VALUES('optimize');
62
JSON1 extension
• Сохраняет JSON как обычный текст
• Предоставляет функции для работы с JSON
• По умолчанию отсутствует
• Можно собрать SQLite c DSQLITE_ENABLE_JSON1
Перенос логики JSON обработки на SQLite уровень
63
Внешние ключи
PRAGMA foreign_keys = ON / OFF(по умолчанию);
64
Внешние ключи
PRAGMA foreign_keys = ON / OFF(по умолчанию);
ON DELETE, ON UPDATE
NO ACTION По умолчанию
64
Внешние ключи
PRAGMA foreign_keys = ON / OFF(по умолчанию);
ON DELETE, ON UPDATE
NO ACTION По умолчанию
RESTRICT Запрещает изменять (удалять) родительский ключ
64
Внешние ключи
PRAGMA foreign_keys = ON / OFF(по умолчанию);
ON DELETE, ON UPDATE
NO ACTION По умолчанию
RESTRICT Запрещает изменять (удалять) родительский ключ
SET NULL Значение дочернего ключа устанавливается в SQL NULL
64
Внешние ключи
PRAGMA foreign_keys = ON / OFF(по умолчанию);
ON DELETE, ON UPDATE
NO ACTION По умолчанию
RESTRICT Запрещает изменять (удалять) родительский ключ
SET NULL Значение дочернего ключа устанавливается в SQL NULL
SET DEFAULT Значение дочернего ключа устанавливается в значение по умолчанию
64
Внешние ключи
PRAGMA foreign_keys = ON / OFF(по умолчанию);
ON DELETE, ON UPDATE
NO ACTION По умолчанию
RESTRICT Запрещает изменять (удалять) родительский ключ
SET NULL Значение дочернего ключа устанавливается в SQL NULL
SET DEFAULT Значение дочернего ключа устанавливается в значение по умолчанию
CASCADE Обновляет значение дочернего ключа или удаляет все строку
64
Ограничения внешних ключей
immediate При ошибке сразу генерируется исключение (по умолчанию)
deferred
Исключение не генерируется пока не вызван COMMIT (при явной
транзакции!)
DEFERRABLE INITIALLY DEFERRED - при описании ключа
CREATE TABLE devs( devId INTEGER PRIMARY KEY, devName TEXT );
CREATE TABLE projects( projectId INTEGER, projectName TEXT, projectDev INTEGER,
FOREIGN KEY (projectDev) REFERENCES devs(devId) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED);
BEGIN;
INSERT INTO projects VALUES(1, 'TestSQLite', 5);
COMMIT;
-> SQL error: foreign key constraint failed
INSERT INTO devs VALUES(5, 'Marvin’);
COMMIT;
65
Новый планировщик (NGQP)
GGQP (SQLite 3.8) всегда может найти такой же или
лучший план
ANALYZE собирая статистику, позволяет выбрать
лучший план
66
Новый планировщик (NGQP)
GGQP (SQLite 3.8) всегда может найти такой же или
лучший план
ANALYZE собирая статистику, позволяет выбрать
лучший план
SQLite гарантирует «СТАБИЛЬНОСТЬ»
Один и тот же план при неизменных условиях:
- неизменность схемы, индексов
- не использования ANALYZE
66
Лучший план (NGQP)
1 Если у вас все в порядке не думайте об этом!
67
Лучший план (NGQP)
2 Используйте индексы
В большинстве случаев индексы позволяют повысить
быстродействие
68
Лучший план (NGQP)
2 Используйте индексы
В большинстве случаев индексы позволяют повысить
быстродействие
3
Не создавайте low-quality
индексы
Low-quality индексы - которые повторяются 10-20 и более
раз. Также, когда значение индекса - enum, bool
68
Лучший план (NGQP)
2 Используйте индексы
В большинстве случаев индексы позволяют повысить
быстродействие
3
Не создавайте low-quality
индексы
Low-quality индексы - которые повторяются 10-20 и более
раз. Также, когда значение индекса - enum, bool
4
Если таки используете low-
quality индексы - запускайте
ANALYZE
ANALYZE sqlite_master вначале использования позволит
собирать статистику
68
Лучший план (NGQP)
2 Используйте индексы
В большинстве случаев индексы позволяют повысить
быстродействие
3
Не создавайте low-quality
индексы
Low-quality индексы - которые повторяются 10-20 и более
раз. Также, когда значение индекса - enum, bool
4
Если таки используете low-
quality индексы - запускайте
ANALYZE
ANALYZE sqlite_master вначале использования позволит
собирать статистику
5 Используйте инструменты Измеряйте!
68
Лучший план (NGQP)
2 Используйте индексы
В большинстве случаев индексы позволяют повысить
быстродействие
3
Не создавайте low-quality
индексы
Low-quality индексы - которые повторяются 10-20 и более
раз. Также, когда значение индекса - enum, bool
4
Если таки используете low-
quality индексы - запускайте
ANALYZE
ANALYZE sqlite_master вначале использования позволит
собирать статистику
5 Используйте инструменты Измеряйте!
6
Специальные решения и
функции - последний довод
INDEXED BY, unary «+», unlikely() и др. - могут оказаться
преждевременной оптимизацией !
68
69
Куда бежать, если заказчик
просит «потюнить» базу?
Code should run as faster as necessary, but no faster.
Richard E. Pattis 70
Локализация проблемы в приложении
• Архитектура
• Логические ошибки и/или
неправильное использование
• Профайлинг
71
Инструменты
72
VACUUM
73
VACUUM
Перестраивает файл базы - аналог дефрагментации
74
VACUUM
Перестраивает файл базы - аналог дефрагментации
Во время вакумирования, копирует весь контент во временную базу,
после чего перезаписывает оригинальный файл. Размер занимаемого
пространства увеличивается вдвое
74
VACUUM
Перестраивает файл базы - аналог дефрагментации
Во время вакумирования, копирует весь контент во временную базу,
после чего перезаписывает оригинальный файл. Размер занимаемого
пространства увеличивается вдвое
Может изменить RowID, если они нигде явно не используются
74
VACUUM
Перестраивает файл базы - аналог дефрагментации
Во время вакумирования, копирует весь контент во временную базу,
после чего перезаписывает оригинальный файл. Размер занимаемого
пространства увеличивается вдвое
Может изменить RowID, если они нигде явно не используются
Не выполнится, если происходит транзакция
74
VACUUM
Перестраивает файл базы - аналог дефрагментации
Во время вакумирования, копирует весь контент во временную базу,
после чего перезаписывает оригинальный файл. Размер занимаемого
пространства увеличивается вдвое
Может изменить RowID, если они нигде явно не используются
Не выполнится, если происходит транзакция
Для WAL ничего не произойдет (
74
pragma auto_vacuum
NONE (0)
(по умолчанию)
Задается на этапе компиляции
SQLITE_DEFAULT_AUTOVACUUM.
FULL (1) Выполняется при каждом комите.
INCREMENTAL (2)
Используется вместе с
pragma incremental_vacuum(N)
N - количество страниц необходимых для выполнения
Не является VACUUM в автоматическом режиме !
Пустые страницы перемещаются в конец файла и затем файл
базы обрезается.
Для смены режима по умолчанию
нужно выполнить настоящий VACUUM
75
Вакуумируем
ROLLBACK
76
Вакуумируем
ROLLBACK
76
Вакуумируем
ROLLBACK
76
Progress handling
sqlite3_progress_handler(sqlite3* D, int N, int(*X)(void*), void* P);
77
Progress handling
sqlite3_progress_handler(sqlite3* D, int N, int(*X)(void*), void* P);
D Соединение
N
Скважность - количество машинных
инструкций относительно вызова
каллбека
X
Каллбек. Установка в NULL или
возврат каллбека < 1 - отключает
обработчик
P Передаваемый параметр
77
Trace hook
int sqlite3_trace_v2(sqlite3* D, unsigned M,
int(*X)(unsigned TC,void* CC,void* PP,void* XP), void *P);
78
Trace hook
int sqlite3_trace_v2(sqlite3* D, unsigned M,
int(*X)(unsigned TC,void* CC,void* PP,void* XP), void *P);
D Соединение
M
SQLITE_TRACE_STMT Когда готово и запускается выражение (sqlite3_stmt)
SQLITE_TRACE_PROFILE На каждом шаге выполнения (sqlite3_step)
SQLITE_TRACE_ROW Когда создается строка вывода (SELECT)
SQLITE_TRACE_CLOSE Когда закрывается соединение
X Каллбек
P Передаваемый параметр
78
Trace hook callback
int(*X)(unsigned T,void* C,void* P,void* X)
T SQLITE_TRACE_STMT SQLITE_TRACE_PROFILE SQLITE_TRACE_ROW SQLITE_TRACE_CLOSE
C Передаваемый параметр
P sqlite3_stmt sqlite3
X «SQL» длительность, ns -
79
ANALYZE
Table
80
ANALYZE
Table
Table
80
ANALYZE
Table
Table
sqlite_stat1
80
ANALYZE
Query
Planner
Table
Table
sqlite_stat1
80
ANALYZE
Query
Planner
Table
Table
sqlite_stat1
80
Попытка оптимизировать базу
Фактически выполняет ANALYZE для таблиц*
pragma OPTIMIZE
81
Попытка оптимизировать базу
Фактически выполняет ANALYZE для таблиц*
Вызывать перед каждым закрытием соединения
или же через каждые 2 часа для длительных
соединений
pragma OPTIMIZE
SQLite советует:
81
Explain query
EXPLAIN QUERY PLAN + «SQL»
DEBUG only!
Показывает используемый план (NGQP)
82
Explain query - результат
select
id
уровень вложенности запроса
order порядок сортировки
from
позиция в FROM выражении для каждого
SELECT совпадения (имеет смысл для
многотабличных запросов)
detail
SCAN • имя таблицы
• использование индексов
(автоиндексы)
• покрытие индекса
• какое выражение WHERE
используется для индекса
SEARCH
83
Explain query - результат
select
id
уровень вложенности запроса
order порядок сортировки
from
позиция в FROM выражении для каждого
SELECT совпадения (имеет смысл для
многотабличных запросов)
detail
SCAN • имя таблицы
• использование индексов
(автоиндексы)
• покрытие индекса
• какое выражение WHERE
используется для индекса
SEARCH
SCAN Полный перебор, медленно
83
Explain query - результат
select
id
уровень вложенности запроса
order порядок сортировки
from
позиция в FROM выражении для каждого
SELECT совпадения (имеет смысл для
многотабличных запросов)
detail
SCAN • имя таблицы
• использование индексов
(автоиндексы)
• покрытие индекса
• какое выражение WHERE
используется для индекса
SEARCH
SCAN Полный перебор, медленно
SEARCH
USING INDEX
Используется индекс, но
данные в оригинальной
таблице, хорошо
83
Explain query - результат
select
id
уровень вложенности запроса
order порядок сортировки
from
позиция в FROM выражении для каждого
SELECT совпадения (имеет смысл для
многотабличных запросов)
detail
SCAN • имя таблицы
• использование индексов
(автоиндексы)
• покрытие индекса
• какое выражение WHERE
используется для индекса
SEARCH
SCAN Полный перебор, медленно
SEARCH
USING INDEX
Используется индекс, но
данные в оригинальной
таблице, хорошо
SEARCH
USING
COVERING
INDEX
Данные уже в таблице с
индексом, максимально
быстро
83
Explain query - результат
select
id
уровень вложенности запроса
order порядок сортировки
from
позиция в FROM выражении для каждого
SELECT совпадения (имеет смысл для
многотабличных запросов)
detail
SCAN • имя таблицы
• использование индексов
(автоиндексы)
• покрытие индекса
• какое выражение WHERE
используется для индекса
SEARCH
SCAN Полный перебор, медленно
SEARCH
USING INDEX
Используется индекс, но
данные в оригинальной
таблице, хорошо
SEARCH
USING
COVERING
INDEX
Данные уже в таблице с
индексом, максимально
быстро
USE TEMP
B-TREE
Пост обработка (пр. - group
by), обычно медленно - лучше
сделать индекс
83
Analyzer
sqlite3_analyzer - утилита, показывает как много и эффективно используется
пространство таблицами и индексами в файле базы
84
Analyzer
sqlite3_analyzer - утилита, показывает как много и эффективно используется
пространство таблицами и индексами в файле базы
84
Оптимизация размеров
Страницы pragma page_size = bytes
Кеша pragma cache_size = kbytes
85
ДБ Профайлер
• Профайлер собирает информацию по
калбекам запрошенных данных (тип
запроса, жизненный цикл)
• Отправляются сигналы для использования
в Instruments (Points of Interests)
• Вывод данных реализован в виде
графиков
Хочется -
[FMDatabase startProfile];
[FMDatabase stopProfile];
Подключение через категорию FMDatabase,
где свайзлится на класс наследника и
переопределяются методы выполнения
86
Пример - ДБ Профайлер
87
ДБ Профайлер + Instruments
Можно
настроить для
отображения
типов запросов
(SELECT,
INSERT …)
88
ДБ Профайлер
90
FMDatabase
91
FMDatabase
91
FMDatabase
FMDatabase Враппер соединения к SQLite базе
FMDatabaseQueue
Сериальная очередь выполнения запросов к базе -
на одном соединении в одном потоке
91
Главный вопрос
оптимизации и всего такого
92
15.6
93
SQLite optimization FAQ
H T T P : / / C O D I F I C A R . C O M . B R / B L O G / S Q L I T E - O P T I M I Z AT I O N - FA Q /
94
SQLite чеклист
Поиск главных вопросов
95
SQLite чеклист
Поиск главных вопросов
1
Режим
доступа
95
SQLite чеклист
Поиск главных вопросов
1 2
Способ
использования
Режим
доступа
95
SQLite чеклист
Поиск главных вопросов
1 2
Способ
использования
Режим
доступа
95
VACUUM
OPTIMAZE (ANALIZE)
1
96
VACUUM
OPTIMAZE (ANALIZE)
1
Смешанный
режим R/W
ДаНетROLLBACK WAL
96
VACUUM
OPTIMAZE (ANALIZE)
1
Смешанный
режим R/W
ДаНетROLLBACK WAL
MultiConnection
Multi-threading
Busy Handlers*
Интенсивное
использование
ДаНет
SingleConnection
Single-threading
Кастомные схемы
доступа
96
VACUUM
OPTIMAZE (ANALIZE)
1
Смешанный
режим R/W
ДаНетROLLBACK WAL
MultiConnection
Multi-threading
Busy Handlers*
Интенсивное
использование
ДаНет
SingleConnection
Single-threading
Кастомные схемы
доступа
FMDatabaseQueue FMDatabase2
96
Trace
Explain query
2
97
Trace
Explain query
Есть явные проблемы в
конкретных запросах ?
Да
Нет, но
все плохо
Нет, все
супер
2
97
Trace
Explain query
Есть явные проблемы в
конкретных запросах ?
Да
Нет, но
все плохо
Используем индексы,
запросы и транзакции, FK,
WithoutRowId, SQL, FTS …
Не помогло /
Хочу еще ?
Да
Нет,
доволен
Меняем логику
(место) работы,
архитектуру
(нормализация и де…,
запросы и транзакции …)
Нет, все
супер
2
97
Trace
Explain query
Есть явные проблемы в
конкретных запросах ?
Да
Нет, но
все плохо
Используем индексы,
запросы и транзакции, FK,
WithoutRowId, SQL, FTS …
Не помогло /
Хочу еще ?
Да
Нет,
доволен
Меняем логику
(место) работы,
архитектуру
(нормализация и де…,
запросы и транзакции …)
Режимы журналов
Auto/manual checkpoint
Shared Cache
Page size
Amalgamation …
Нет, все
супер
2
1
97
98
Источники
http://www.sqlite.org
http://www.sqlitetutorial.net
http://zametkinapolyah.ru/zametki-o-mysql/sqlite/
http://stackoverflow.com/questions/tagged/sqlite
https://lmgtfy.com/?q=sqlite
Using SQLite. Jay A. Kreibich, O’REILLY
99
Путеводитель SQLite
для разработчика
Спикер:

Василий Сидненко
100

More Related Content

What's hot

Android - 13 - Database
Android - 13 - DatabaseAndroid - 13 - Database
Android - 13 - Database
Noveo
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5
Technopark
 
Артём Кошелев: Прочная основа для автоматизации тестирования
Артём Кошелев: Прочная основа для автоматизации тестированияАртём Кошелев: Прочная основа для автоматизации тестирования
Артём Кошелев: Прочная основа для автоматизации тестирования
Yandex
 
Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)
Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)
Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)Dmytro Zharii
 
C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.
Igor Shkulipa
 
Читабельные отчеты для автоматизации на C# / Gallio / BDDfy
Читабельные отчеты для автоматизации на C# / Gallio / BDDfyЧитабельные отчеты для автоматизации на C# / Gallio / BDDfy
Читабельные отчеты для автоматизации на C# / Gallio / BDDfy
Dmytro Zharii
 
C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.
Igor Shkulipa
 
C++ STL & Qt. Занятие 02.
C++ STL & Qt. Занятие 02.C++ STL & Qt. Занятие 02.
C++ STL & Qt. Занятие 02.
Igor Shkulipa
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Dev2Dev
 
C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.
Igor Shkulipa
 
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
Dmytro Zharii
 
Клиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталяхКлиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталяхKirill Zotin
 
Контроль качества высоконагруженных систем / Андрей Дроздов (Avito)
Контроль качества высоконагруженных систем / Андрей Дроздов (Avito)Контроль качества высоконагруженных систем / Андрей Дроздов (Avito)
Контроль качества высоконагруженных систем / Андрей Дроздов (Avito)
Ontico
 
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.
Igor Shkulipa
 
C++ STL & Qt. Занятие 01.
C++ STL & Qt. Занятие 01.C++ STL & Qt. Занятие 01.
C++ STL & Qt. Занятие 01.
Igor Shkulipa
 
Оптимизация UI потока / Дмитрий Куркин (Mail.Ru)
Оптимизация UI потока / Дмитрий Куркин (Mail.Ru)Оптимизация UI потока / Дмитрий Куркин (Mail.Ru)
Оптимизация UI потока / Дмитрий Куркин (Mail.Ru)
Ontico
 
Общество Мертвых Потоков
Общество Мертвых ПотоковОбщество Мертвых Потоков
Общество Мертвых Потоков
Alexey Fyodorov
 
SPA инструменты
SPA инструментыSPA инструменты
SPA инструменты
Roman Dvornov
 
Java весна 2013 лекция 9
Java весна 2013 лекция 9Java весна 2013 лекция 9
Java весна 2013 лекция 9Technopark
 
микроСЕРВИСЫ: огонь, вода и медные трубы
микроСЕРВИСЫ: огонь, вода и медные трубымикроСЕРВИСЫ: огонь, вода и медные трубы
микроСЕРВИСЫ: огонь, вода и медные трубы
Aleksandr Tarasov
 

What's hot (20)

Android - 13 - Database
Android - 13 - DatabaseAndroid - 13 - Database
Android - 13 - Database
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5
 
Артём Кошелев: Прочная основа для автоматизации тестирования
Артём Кошелев: Прочная основа для автоматизации тестированияАртём Кошелев: Прочная основа для автоматизации тестирования
Артём Кошелев: Прочная основа для автоматизации тестирования
 
Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)
Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)
Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)
 
C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.
 
Читабельные отчеты для автоматизации на C# / Gallio / BDDfy
Читабельные отчеты для автоматизации на C# / Gallio / BDDfyЧитабельные отчеты для автоматизации на C# / Gallio / BDDfy
Читабельные отчеты для автоматизации на C# / Gallio / BDDfy
 
C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.
 
C++ STL & Qt. Занятие 02.
C++ STL & Qt. Занятие 02.C++ STL & Qt. Занятие 02.
C++ STL & Qt. Занятие 02.
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
 
C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.
 
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
 
Клиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталяхКлиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталях
 
Контроль качества высоконагруженных систем / Андрей Дроздов (Avito)
Контроль качества высоконагруженных систем / Андрей Дроздов (Avito)Контроль качества высоконагруженных систем / Андрей Дроздов (Avito)
Контроль качества высоконагруженных систем / Андрей Дроздов (Avito)
 
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.
 
C++ STL & Qt. Занятие 01.
C++ STL & Qt. Занятие 01.C++ STL & Qt. Занятие 01.
C++ STL & Qt. Занятие 01.
 
Оптимизация UI потока / Дмитрий Куркин (Mail.Ru)
Оптимизация UI потока / Дмитрий Куркин (Mail.Ru)Оптимизация UI потока / Дмитрий Куркин (Mail.Ru)
Оптимизация UI потока / Дмитрий Куркин (Mail.Ru)
 
Общество Мертвых Потоков
Общество Мертвых ПотоковОбщество Мертвых Потоков
Общество Мертвых Потоков
 
SPA инструменты
SPA инструментыSPA инструменты
SPA инструменты
 
Java весна 2013 лекция 9
Java весна 2013 лекция 9Java весна 2013 лекция 9
Java весна 2013 лекция 9
 
микроСЕРВИСЫ: огонь, вода и медные трубы
микроСЕРВИСЫ: огонь, вода и медные трубымикроСЕРВИСЫ: огонь, вода и медные трубы
микроСЕРВИСЫ: огонь, вода и медные трубы
 

Similar to Путеводитель SQLite для разработчика

Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"
Yandex
 
Deployment to production with an unexpected load
Deployment to production with an unexpected loadDeployment to production with an unexpected load
Deployment to production with an unexpected load
Grid Dynamics
 
Распределенные системы в Одноклассниках
Распределенные системы в ОдноклассникахРаспределенные системы в Одноклассниках
Распределенные системы в Одноклассниках
odnoklassniki.ru
 
Тестирование серверной конфигурации
Тестирование серверной конфигурацииТестирование серверной конфигурации
Тестирование серверной конфигурации
Timur Batyrshin
 
QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"
QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"
QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"
Provectus
 
Jbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterJbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot Starter
Aleksandr Tarasov
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned
Alexander Syrotenko
 
Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
Badoo Development
 
Асинхронная репликация без цензуры: архитектурные проблемы MySQL, или почему ...
Асинхронная репликация без цензуры: архитектурные проблемы MySQL, или почему ...Асинхронная репликация без цензуры: архитектурные проблемы MySQL, или почему ...
Асинхронная репликация без цензуры: архитектурные проблемы MySQL, или почему ...
Oleg Tsarev
 
UWDC 2013, Как мы используем Yii
UWDC 2013, Как мы используем YiiUWDC 2013, Как мы используем Yii
UWDC 2013, Как мы используем YiiAlexander Makarov
 
React со скоростью света: не совсем обычный серверный рендеринг
React со скоростью света: не совсем обычный серверный рендерингReact со скоростью света: не совсем обычный серверный рендеринг
React со скоростью света: не совсем обычный серверный рендеринг
Timophy Chaptykov
 
Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложений
Andrey Akinshin
 
TК°Conf. Stylelint — как и зачем линтить CSS. Андрей Ситник.
TК°Conf. Stylelint — как и зачем линтить CSS. Андрей Ситник.TК°Conf. Stylelint — как и зачем линтить CSS. Андрей Ситник.
TК°Conf. Stylelint — как и зачем линтить CSS. Андрей Ситник.
TKConf
 
Sql injection
Sql injectionSql injection
Sql injection
Michal11221
 
My talk on DevOps engineer's adventures in the Windows world at UWDC 2017
My talk on DevOps engineer's adventures in the Windows world at UWDC 2017My talk on DevOps engineer's adventures in the Windows world at UWDC 2017
My talk on DevOps engineer's adventures in the Windows world at UWDC 2017
Alex Chistyakov
 
Java осень 2014 занятие 6
Java осень 2014 занятие 6Java осень 2014 занятие 6
Java осень 2014 занятие 6
Technopark
 
Эволюционный дизайн. Joker Students Day 2016
Эволюционный дизайн. Joker Students Day 2016Эволюционный дизайн. Joker Students Day 2016
Эволюционный дизайн. Joker Students Day 2016
Кирилл Толкачёв
 
2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels
Nikolay Samokhvalov
 
Тимур Лукин - Архитектура и проектирование ПО
Тимур Лукин - Архитектура и проектирование ПОТимур Лукин - Архитектура и проектирование ПО
Тимур Лукин - Архитектура и проектирование ПОYandex
 

Similar to Путеводитель SQLite для разработчика (20)

Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"Михаил Давыдов "Масштабируемые JavaScript-приложения"
Михаил Давыдов "Масштабируемые JavaScript-приложения"
 
Deployment to production with an unexpected load
Deployment to production with an unexpected loadDeployment to production with an unexpected load
Deployment to production with an unexpected load
 
Распределенные системы в Одноклассниках
Распределенные системы в ОдноклассникахРаспределенные системы в Одноклассниках
Распределенные системы в Одноклассниках
 
Тестирование серверной конфигурации
Тестирование серверной конфигурацииТестирование серверной конфигурации
Тестирование серверной конфигурации
 
QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"
QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"
QA MeetUp - Тимур Батыршин: "Тестирование серверной конфигурации"
 
Jbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterJbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot Starter
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned
 
Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
 
Асинхронная репликация без цензуры: архитектурные проблемы MySQL, или почему ...
Асинхронная репликация без цензуры: архитектурные проблемы MySQL, или почему ...Асинхронная репликация без цензуры: архитектурные проблемы MySQL, или почему ...
Асинхронная репликация без цензуры: архитектурные проблемы MySQL, или почему ...
 
UWDC 2013, Как мы используем Yii
UWDC 2013, Как мы используем YiiUWDC 2013, Как мы используем Yii
UWDC 2013, Как мы используем Yii
 
React со скоростью света: не совсем обычный серверный рендеринг
React со скоростью света: не совсем обычный серверный рендерингReact со скоростью света: не совсем обычный серверный рендеринг
React со скоростью света: не совсем обычный серверный рендеринг
 
Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложений
 
TК°Conf. Stylelint — как и зачем линтить CSS. Андрей Ситник.
TК°Conf. Stylelint — как и зачем линтить CSS. Андрей Ситник.TК°Conf. Stylelint — как и зачем линтить CSS. Андрей Ситник.
TК°Conf. Stylelint — как и зачем линтить CSS. Андрей Ситник.
 
Sql injection
Sql injectionSql injection
Sql injection
 
My talk on DevOps engineer's adventures in the Windows world at UWDC 2017
My talk on DevOps engineer's adventures in the Windows world at UWDC 2017My talk on DevOps engineer's adventures in the Windows world at UWDC 2017
My talk on DevOps engineer's adventures in the Windows world at UWDC 2017
 
Java осень 2014 занятие 6
Java осень 2014 занятие 6Java осень 2014 занятие 6
Java осень 2014 занятие 6
 
Эволюционный дизайн. Joker Students Day 2016
Эволюционный дизайн. Joker Students Day 2016Эволюционный дизайн. Joker Students Day 2016
Эволюционный дизайн. Joker Students Day 2016
 
2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels2014.12.23 Александр Андреев, Parallels
2014.12.23 Александр Андреев, Parallels
 
Тимур Лукин - Архитектура и проектирование ПО
Тимур Лукин - Архитектура и проектирование ПОТимур Лукин - Архитектура и проектирование ПО
Тимур Лукин - Архитектура и проектирование ПО
 
PT MIFI Labsql
PT MIFI LabsqlPT MIFI Labsql
PT MIFI Labsql
 

Путеводитель SQLite для разработчика

  • 2. SQLite «Когда вам хочется что-либо по-настоящему понять, нет лучшего способа, чем попытаться втолковать это кому-то другому» Д.Адамс 2
  • 3. Куда бежать, если заказчик просит «потюнить» базу ? 3
  • 4. Как это бывает… • используете SQLite • протестировали и видите проблемы • заказчик видит проблемы и просит улучшить • не видит проблем и просит улучшить 4
  • 5. Что вначале делает разработчик 5
  • 6. Что вначале делает разработчик Нормально же общались… 5
  • 7. Что пытается делать разработчик • использовать силу убеждения • использовать силу переименования • использовать силу GCD • использовать силу 6
  • 8. Что советует делать более опытный разработчик использовать силу комбинаторики - pragma , mode … 7
  • 9. Что в результате делает разработчик открывает sqlite.org 8
  • 10. Что мы знаем о SQLite «Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, - недооценка изобретательности клинических идиотов» Д.Адамс 9
  • 11. SQLITE IS BIG. REALLY BIGYou just won’t believe how vastly, hugely, mind-bogglingly big it is. 10
  • 12. Особенности SQLite • встраиваемая, кроссплатформенная • открытый доступ, покрытие тестами 100500+ • единый файл, без сервера * • нет учетных записей (ролей) • тип данных в столбце - условный • множественные подключения • дополнительный функционал * 11
  • 15. SQLite library libsqlite3 всегда указывает на последнюю версию в системе 13
  • 16. SQLite API - Жизненный цикл sqlite3_open Создает конекшн к новой или существующей базе. Возвращает объект sqlite3. (Конструктор). 14
  • 17. SQLite API - Жизненный цикл sqlite3_open Создает конекшн к новой или существующей базе. Возвращает объект sqlite3. (Конструктор). sqlite3_prepare Преобразовывает(компилирует) стринговый SQL запрос в бинарный объект - sqlite3_stmt. (Конструктор). 14
  • 18. SQLite API - Жизненный цикл sqlite3_open Создает конекшн к новой или существующей базе. Возвращает объект sqlite3. (Конструктор). sqlite3_prepare Преобразовывает(компилирует) стринговый SQL запрос в бинарный объект - sqlite3_stmt. (Конструктор). sqlite3_bind Сохраняет данные в параметры выражения (Биндинг) 14
  • 19. SQLite API - Жизненный цикл sqlite3_open Создает конекшн к новой или существующей базе. Возвращает объект sqlite3. (Конструктор). sqlite3_prepare Преобразовывает(компилирует) стринговый SQL запрос в бинарный объект - sqlite3_stmt. (Конструктор). sqlite3_bind Сохраняет данные в параметры выражения (Биндинг) sqlite3_step Выполняет созданное выражение (sqlite3_stmt), возвращает указатель на первую (и последующие при вызове) строки результата 14
  • 20. SQLite API - Жизненный цикл sqlite3_open Создает конекшн к новой или существующей базе. Возвращает объект sqlite3. (Конструктор). sqlite3_prepare Преобразовывает(компилирует) стринговый SQL запрос в бинарный объект - sqlite3_stmt. (Конструктор). sqlite3_bind Сохраняет данные в параметры выражения (Биндинг) sqlite3_step Выполняет созданное выражение (sqlite3_stmt), возвращает указатель на первую (и последующие при вызове) строки результата sqlite3_column Возвращает значение столбца в выполненном выражении. «Абстрактный». Используются - sqlite3_column_text(), sqlite3_column_int() … 14
  • 21. SQLite API - Жизненный цикл sqlite3_open Создает конекшн к новой или существующей базе. Возвращает объект sqlite3. (Конструктор). sqlite3_prepare Преобразовывает(компилирует) стринговый SQL запрос в бинарный объект - sqlite3_stmt. (Конструктор). sqlite3_bind Сохраняет данные в параметры выражения (Биндинг) sqlite3_step Выполняет созданное выражение (sqlite3_stmt), возвращает указатель на первую (и последующие при вызове) строки результата sqlite3_column Возвращает значение столбца в выполненном выражении. «Абстрактный». Используются - sqlite3_column_text(), sqlite3_column_int() … sqlite3_finalize Деструктор выражения (sqlite3_stmt) 14
  • 22. SQLite API - Жизненный цикл sqlite3_open Создает конекшн к новой или существующей базе. Возвращает объект sqlite3. (Конструктор). sqlite3_prepare Преобразовывает(компилирует) стринговый SQL запрос в бинарный объект - sqlite3_stmt. (Конструктор). sqlite3_bind Сохраняет данные в параметры выражения (Биндинг) sqlite3_step Выполняет созданное выражение (sqlite3_stmt), возвращает указатель на первую (и последующие при вызове) строки результата sqlite3_column Возвращает значение столбца в выполненном выражении. «Абстрактный». Используются - sqlite3_column_text(), sqlite3_column_int() … sqlite3_finalize Деструктор выражения (sqlite3_stmt) sqlite3_close Закрывает соединение. Деструктор (sqlite3). 14
  • 23. SQLite API - Настройки sqlite3_config • настройка выделения памяти • логирования • кеш • threading model • sqlite3_db_config - для конкретного соединения 15
  • 24. SQLite API - Настройки sqlite3_config • настройка выделения памяти • логирования • кеш • threading model • sqlite3_db_config - для конкретного соединения pragma • изменение самой библиотеки или запросов к не табличным данным • нет обратной совместимости • нет ошибок • разный эффект на разных стадиях жизненного цикла • можно применять к конкретному соединению 15
  • 26. Amalgamation • SQLite проект содержит более 100 отдельных файлов • Amalgamation - объединение всего, что нужно в одном .c файле • Содержит более 180000 строк кода и весит более 6 MB • Предназначен для кастомной сборки SQLite 17
  • 28. Command-Line Shell - sqlite3 19
  • 29. SQLite и многопоточность // Что если я тебе скажу / * что с sqlite можно работать из разных потоков */ 20
  • 30. Threading mode - режимы Single-Thread Не защищенный режим. Не используются никакие средства синхронизации потоков. Работать более чем в одном потоке не безопасно! 21
  • 31. Threading mode - режимы Single-Thread Не защищенный режим. Не используются никакие средства синхронизации потоков. Работать более чем в одном потоке не безопасно! Multi-Thread Нельзя использовать несколько потоков для одного соединения, но можно использовать отдельный поток для каждого соединения. 21
  • 32. Threading mode - режимы Single-Thread Не защищенный режим. Не используются никакие средства синхронизации потоков. Работать более чем в одном потоке не безопасно! Multi-Thread Нельзя использовать несколько потоков для одного соединения, но можно использовать отдельный поток для каждого соединения. Serialized (default *) Безопасный режим, но все запросы выполняются последовательно. 21
  • 33. Threading mode - настройка Compile-time Компиляция SQLite compile-time - параметр SQLITE_THREADSAFE или -DSQLITE_THREADSAFE=1 -DSQLITE_THREADSAFE=2 22
  • 34. Threading mode - настройка Compile-time Start-time Компиляция SQLite compile-time - параметр SQLITE_THREADSAFE или -DSQLITE_THREADSAFE=1 -DSQLITE_THREADSAFE=2 Инициализация SQLite sqlite3_config() - параметр SQLITE_CONFIG_SINGLETHREAD SQLITE_CONFIG_MULTITHREAD SQLITE_CONFIG_SERIALIZED 22
  • 35. Threading mode - настройка Compile-time Start-time Run-time Компиляция SQLite compile-time - параметр SQLITE_THREADSAFE или -DSQLITE_THREADSAFE=1 -DSQLITE_THREADSAFE=2 Инициализация SQLite sqlite3_config() - параметр SQLITE_CONFIG_SINGLETHREAD SQLITE_CONFIG_MULTITHREAD SQLITE_CONFIG_SERIALIZED Открытие соединения sqlite3_open() - параметр SQLITE_OPEN_NOMUTEX SQLITE_OPEN_FULLMUTEX 22
  • 37. Потокобезопасность sqlite3_threadsafe() Показывает параметр компиляции - DSQLITE_THREADSAFE, а не реальный режим доступа! 24
  • 40. Threading mode По умолчанию SQLite не в Serialized режиме! 26
  • 41. Threading mode По умолчанию SQLite не в Serialized режиме! 26
  • 42. Threading mode По умолчанию SQLite не в Serialized режиме! Устанавливаем Serialized 26
  • 43. Многопоточность Для управления режимом - просто включите его Только на этапе инициализации SQLite можно установить любой режим Хороший тон - принудительная инициализация и выключение SQLite sqlite3_initialize(); sqlite3_shutdown(); 27
  • 44. Тест 1 - Единое Соединение Single-Thread NO Multi-Thread NO Serialized YES 28
  • 45. Тест 1 - Единое Соединение Single-Thread NO Multi-Thread NO Serialized YES ConnectionSQLite Thread 1 Thread 2 28
  • 46. Тест 2 - Отдельные соединения Single-Thread NO Multi-Thread YES Serialized YES 29
  • 47. Тест 2 - Отдельные соединения Thread 1 Connection 1 SQLite Thread 2 Connection 2 Single-Thread NO Multi-Thread YES Serialized YES 29
  • 48. Многопоточный доступ Connection Read- Write Thread Serialized Multi-Thread Single-Thread (!) Single R 1 OK Crash Crash 2 OK R-W 1 OK-OK Crash Crash 2 OK-OK Multi R 1 OK OK OK (!) 2 OK OK OK (!) R-W 1 OK-OK (OK-BUSY) OK-OK (OK-BUSY) OK-OK (OK-BUSY) (!) 2 OK-BUSY OK-BUSY OK-BUSY (!) 30
  • 49. SQLite File Locking (classic*) • механизм управления блокировкой и конкурентным доступом • является главным инструментом реализации ACID • напрямую связан с понятием транзакции • устанавливается с помощью pragma locking_mode SQLITE_BUSY - это все о нем 31
  • 50. File Locking - modes NORMAL (по умолчанию) sqlite3_exec(connection, "PRAGMA locking_mode=NORMAL", NULL, NULL, NULL); SQLite будет будет устанавливать (lock) и сбрасывать блокировку (unlock) для каждой транзакции. EXCLUSIVE sqlite3_exec(connection, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, NULL); SQLite заблокирует базу на все время жизни соединения. Для временых («») и в памяти («:memory:») баз является единственно возможным 32
  • 51. File Locking - обработка sqlite3_busy_timeout (connection, 1000) SQLite будет пытаться получить доступ к ресурсу (после SQLITE_BUSY) в течении интервала (mc) sqlite3_busy_handler (connection, &sqliteCallback, NULL) Определяемый каллбек вызывается при получении SQLITE_BUSY. Если каллбек возвращает 0, клиенту перенаправляется SQLITE_BUSY, иначе SQLite снова пытается получить доступ 33
  • 52. Используем locking handlers Connection Read- Write Thread Serialized Multi-Thread Single-Thread (!) Single R 1 OK Crash Crash 2 OK R-W 1 OK-OK Crash Crash 2 OK-OK Multi R 1 OK OK OK (!) 2 OK OK OK (!) R-W 1 OK-OK OK-OK OK-OK (!) 2 OK-OK OK-OK OK-OK (OK-BUSY) (!) 34
  • 54. Shared-Cache Thread 1 SQLite Connection 1 Thread 2 Connection 2 Connection 3 Shared Cache Normal Locking Mode Shared- Cache Locking Mode 35
  • 55. SQLite Shared-Cache Mode sqlite3_enable_shared_cache() * *кроме Mac OSX 10.7 и iOS 5 Установка режима для ВСЕХ соединений базы Mac OSX 10.7 и iOS 5 Параметр открытия соединения SQLITE_OPEN_SHAREDCACHE - добавляет КОНКРЕТНОЕ соединение в шаред кеш Позволяет существенно уменьшить потребление памяти для I/O операций Отключен по умолчанию Добавляет новую модель блокировки - «shared cache locking model» 36
  • 56. Shared-Cache Locking Model Transaction Level Locking Запись - только ОДНА транзакция в один момент времени Чтение - не ограничено Table Level Locking Запись - только ОДИН (write-lock) для таблицы в один момент времени Чтение - (read-lock) не ограничено Serialized mode (по умолчанию) Данные синхронизированы с записью в таблицу. Чтение вернет либо данные ДО записи, либо УЖЕ ПОСЛЕ записи. Read-Uncommitted mode Данные НЕ синхронизированы с записью. Возможно получение не консистентных данных ! PRAGMA read_uncommitted = <boolean>; Schema Level Locking Поддерживает Table Level Locking с ограничениями * 37
  • 57. Shared cache Connection Read- Write Serialized Multi-Thread Single-Thread (!) Multi R OK OK SQLITE_CORRUPT CRASH OK OK R-W OK-OK OK-OK OK-OK OK-OK 38
  • 59. Транзакция • Атомарность (atomicity) • Согласованность (consistency) 39
  • 60. Транзакция • Атомарность (atomicity) • Согласованность (consistency) • Изолированность (isolation) 39
  • 61. Транзакция • Атомарность (atomicity) • Согласованность (consistency) • Изолированность (isolation) • Долговечность (durability) ACID 39
  • 62. Транзакция Главный инструмент реализации - журнал Создается Явно BEGIN … COMMIT Не явно 40
  • 63. Атомарный комит • Во время транзакции изменения применяются полностью, либо совсем не происходят 41
  • 64. Атомарный комит • Во время транзакции изменения применяются полностью, либо совсем не происходят • Rollback mode - стандартный режим реализации с временным журналом 41
  • 65. Атомарный комит • Во время транзакции изменения применяются полностью, либо совсем не происходят • Rollback mode - стандартный режим реализации с временным журналом • WAL (write-ahead log) mode - новый режим с постоянным журналом 41
  • 67. Атомарный комит 1 Исходное состояние - 2 Запрос на чтение. BEGIN Shared Lock 1 2 42
  • 68. Атомарный комит 1 Исходное состояние - 2 Запрос на чтение. BEGIN Shared Lock 3 Чтение Reserved Lock 1 2 3 42
  • 69. Атомарный комит 1 Исходное состояние - 2 Запрос на чтение. BEGIN Shared Lock 3 Чтение Reserved Lock4 Создание журнала и запись в него изменений 1 2 34 42
  • 70. Атомарный комит 1 Исходное состояние - 2 Запрос на чтение. BEGIN Shared Lock 3 Чтение Reserved Lock4 Создание журнала и запись в него изменений 5 Запись журнала на диск. 1 2 345 42
  • 71. Атомарный комит 1 Исходное состояние - 2 Запрос на чтение. BEGIN Shared Lock 3 Чтение Reserved Lock4 Создание журнала и запись в него изменений 5 Запись журнала на диск. 6 Запись изменений в базу(в памяти) Exclusive lock 1 2 3456 42
  • 72. Атомарный комит 1 Исходное состояние - 2 Запрос на чтение. BEGIN Shared Lock 3 Чтение Reserved Lock4 Создание журнала и запись в него изменений 5 Запись журнала на диск. 6 Запись изменений в базу(в памяти) Exclusive lock7 Запись базы на диск 1 2 3456 7 42
  • 73. Атомарный комит 1 Исходное состояние - 2 Запрос на чтение. BEGIN Shared Lock 3 Чтение Reserved Lock4 Создание журнала и запись в него изменений 5 Запись журнала на диск. 6 Запись изменений в базу(в памяти) Exclusive lock7 Запись базы на диск 8 Удаление журнала. COMMIT 1 2 3456 7 8 42
  • 74. Атомарный комит 1 Исходное состояние - 2 Запрос на чтение. BEGIN Shared Lock 3 Чтение Reserved Lock4 Создание журнала и запись в него изменений 5 Запись журнала на диск. 6 Запись изменений в базу(в памяти) Exclusive lock7 Запись базы на диск 8 Удаление журнала. COMMIT 9 Исходное состояние с изменениями - 1 2 3456 7 89 42
  • 76. Rollback 7 Hot journal Shared lock 7 44
  • 77. Rollback 7 Hot journal Shared lock 8 Запись не выполненных изменений Exclusive lock 7 8 44
  • 78. Rollback 7 Hot journal Shared lock 8 Запись не выполненных изменений Exclusive lock 9 Удаление журнала 7 8 9 44
  • 79. Rollback 7 Hot journal Shared lock 8 Запись не выполненных изменений Exclusive lock 9 Удаление журнала 10 Исходное состояние с изменениями - 7 8 9 10 44
  • 80. Rollback Вызов ROLLBACK во время транзакции просто удаляет журнал 45
  • 81. Синхронизация транзакции OFF SQLite считает данные записанными сразу после передачи ОС, то есть целостность данных зависит от работы системы. 46
  • 82. Синхронизация транзакции OFF SQLite считает данные записанными сразу после передачи ОС, то есть целостность данных зависит от работы системы. NORMAL Компромиссный режим при котором возможна маленькая вероятность потери данных при креше системы 46
  • 83. Синхронизация транзакции OFF SQLite считает данные записанными сразу после передачи ОС, то есть целостность данных зависит от работы системы. NORMAL Компромиссный режим при котором возможна маленькая вероятность потери данных при креше системы FULL (по умолчанию) Гарантия целостности данных в любых ситуациях. 46
  • 84. Синхронизация транзакции OFF SQLite считает данные записанными сразу после передачи ОС, то есть целостность данных зависит от работы системы. NORMAL Компромиссный режим при котором возможна маленькая вероятность потери данных при креше системы FULL (по умолчанию) Гарантия целостности данных в любых ситуациях. EXTRA Гарантия гарантии целостности в любых любых ситуациях 46
  • 85. Режимы журнала DELETE (по умолчанию) Журнал удаляется после транзакции 47
  • 86. Режимы журнала DELETE (по умолчанию) Журнал удаляется после транзакции TRANCATE Журнал обрезается до нуля (может работать быстрее чем создание/удаление) 47
  • 87. Режимы журнала DELETE (по умолчанию) Журнал удаляется после транзакции TRANCATE Журнал обрезается до нуля (может работать быстрее чем создание/удаление) PERSIST Журнал заполняется нулями, размер не изменяется 47
  • 88. Режимы журнала DELETE (по умолчанию) Журнал удаляется после транзакции TRANCATE Журнал обрезается до нуля (может работать быстрее чем создание/удаление) PERSIST Журнал заполняется нулями, размер не изменяется WAL Постоянный журнал. Работает быстрее. Предпочтительный. Запись и чтение не блокируют друг друга* 47
  • 89. Режимы журнала DELETE (по умолчанию) Журнал удаляется после транзакции TRANCATE Журнал обрезается до нуля (может работать быстрее чем создание/удаление) PERSIST Журнал заполняется нулями, размер не изменяется WAL Постоянный журнал. Работает быстрее. Предпочтительный. Запись и чтение не блокируют друг друга* MEMORY Журнал в оперативной памяти. Быстро но не надежно 47
  • 90. Режимы журнала DELETE (по умолчанию) Журнал удаляется после транзакции TRANCATE Журнал обрезается до нуля (может работать быстрее чем создание/удаление) PERSIST Журнал заполняется нулями, размер не изменяется WAL Постоянный журнал. Работает быстрее. Предпочтительный. Запись и чтение не блокируют друг друга* MEMORY Журнал в оперативной памяти. Быстро но не надежно OFF Без журнала - без транзакций 47
  • 91. WAL (Write-Ahead Logging) Преимущества Существенно быстрее Писатели не блокируют читателей Операции I/O более упорядочены Меньше обращается к диску (fsync()) 48
  • 92. WAL (Write-Ahead Logging) Преимущества Существенно быстрее Писатели не блокируют читателей Операции I/O более упорядочены Меньше обращается к диску (fsync()) Недостатки Не работает с распределенным доступом (по сети) Невозможно изменить размер страницы ( page_size ) Невозможно создать соединение только для чтения Может быть чуть медленней (1-2%), если в основном происходит чтение База имеет постоянные дополнительные файлы - «-shm», «-wal» Дополнительная операция - чекпоинт (checkpoint) 48
  • 93. WAL Commit Checkpoint Означает что изменения сохранились в журнал Означает перенос изменений из журнала в файл базы Изменения попадают в файл базы только после чекпоинта (checkpoint) Автоматически - по значению порога журнала - 1000 страниц (~4Mb) SQLITE_DEFAULT_WAL_AUTOCHECKPOINT Порог авточекпоинта может быть изменен PRAGMA wal_autocheckpoint=N; Авточекпоинт может быть отключен (PRAGMA wal_autocheckpoint=0), тогда он должен выполнятся вручную sqlite3_wal_checkpoint_v2() 49
  • 94. 1 Исходное состояние 1 db wal shm Writer w0 Reader wem0 wem - writer end-markrem - reader end-mark w - comit-reader -writer WAL - R/W 50
  • 95. 1 Исходное состояние 2 Получение валидного комита (wem0) , сохранение своего (rem1) 1 db wal shm Writer w0 Reader wem0 2 db wal shm Writer w0 rem1 Reader wem0 wem - writer end-markrem - reader end-mark w - comit-reader -writer WAL - R/W 50
  • 96. 1 Исходное состояние 2 Получение валидного комита (wem0) , сохранение своего (rem1) 3 Чтение от rem1 журнала и по всему файлу базы 1 db wal shm Writer w0 Reader wem0 2 db wal shm Writer w0 rem1 Reader wem0 3 db wal shm Writer w0 rem1 Reader wem0 wem - writer end-markrem - reader end-mark w - comit-reader -writer WAL - R/W 50
  • 97. 1 Исходное состояние 2 Получение валидного комита (wem0) , сохранение своего (rem1) 3 Чтение от rem1 журнала и по всему файлу базы 4 Удаление своего rem1 1 db wal shm Writer w0 Reader wem0 2 db wal shm Writer w0 rem1 Reader wem0 3 db wal shm Writer w0 rem1 Reader wem0 4 db wal shm Writer w0 rem1 Reader wem0 wem - writer end-markrem - reader end-mark w - comit-reader -writer WAL - R/W 50
  • 98. 1 Исходное состояние 2 Получение валидного комита (wem0) , сохранение своего (rem1) 3 Чтение от rem1 журнала и по всему файлу базы 4 Удаление своего rem1 5 Получение валидного комита (wem0) 1 db wal shm Writer w0 Reader wem0 2 db wal shm Writer w0 rem1 Reader wem0 3 db wal shm Writer w0 rem1 Reader wem0 4 db wal shm Writer w0 rem1 Reader wem0 5 db wal shm Writer w0 Reader wem0 wem - writer end-markrem - reader end-mark w - comit-reader -writer WAL - R/W 50
  • 99. 1 Исходное состояние 2 Получение валидного комита (wem0) , сохранение своего (rem1) 3 Чтение от rem1 журнала и по всему файлу базы 4 Удаление своего rem1 5 Получение валидного комита (wem0) 6 Запись изменений в журнал после w0 1 db wal shm Writer w0 Reader wem0 2 db wal shm Writer w0 rem1 Reader wem0 3 db wal shm Writer w0 rem1 Reader wem0 4 db wal shm Writer w0 rem1 Reader wem0 5 db wal shm Writer w0 Reader wem0 6 db wal shm Writer w0 Reader wem0 w1 wem - writer end-markrem - reader end-mark w - comit-reader -writer WAL - R/W 50
  • 100. 1 Исходное состояние 2 Получение валидного комита (wem0) , сохранение своего (rem1) 3 Чтение от rem1 журнала и по всему файлу базы 4 Удаление своего rem1 5 Получение валидного комита (wem0) 6 Запись изменений в журнал после w0 7 Запись журнала w1 на диск 1 db wal shm Writer w0 Reader wem0 2 db wal shm Writer w0 rem1 Reader wem0 3 db wal shm Writer w0 rem1 Reader wem0 4 db wal shm Writer w0 rem1 Reader wem0 5 db wal shm Writer w0 Reader wem0 6 db wal shm Writer w0 Reader wem0 w1 7 db wal shm Writer w0 Reader wem0 w1 wal disk w1 wem - writer end-markrem - reader end-mark w - comit-reader -writer WAL - R/W 50
  • 101. 1 Исходное состояние 2 Получение валидного комита (wem0) , сохранение своего (rem1) 3 Чтение от rem1 журнала и по всему файлу базы 4 Удаление своего rem1 5 Получение валидного комита (wem0) 6 Запись изменений в журнал после w0 7 Запись журнала w1 на диск 8 Обновление в shm последнего комита (wem1). COMMIT 1 db wal shm Writer w0 Reader wem0 2 db wal shm Writer w0 rem1 Reader wem0 3 db wal shm Writer w0 rem1 Reader wem0 4 db wal shm Writer w0 rem1 Reader wem0 5 db wal shm Writer w0 Reader wem0 6 db wal shm Writer w0 Reader wem0 w1 7 db wal shm Writer w0 Reader wem0 w1 wal disk w1 8 db wal shm Writer w0 Reader wem0 w1 wem1 wem - writer end-markrem - reader end-mark w - comit-reader -writer WAL - R/W 50
  • 102. 1 Исходное состояние 2 Получение валидного комита (wem0) , сохранение своего (rem1) 3 Чтение от rem1 журнала и по всему файлу базы 4 Удаление своего rem1 5 Получение валидного комита (wem0) 6 Запись изменений в журнал после w0 7 Запись журнала w1 на диск 8 Обновление в shm последнего комита (wem1). COMMIT 9 Исходное состояние с изменениями 1 db wal shm Writer w0 Reader wem0 2 db wal shm Writer w0 rem1 Reader wem0 3 db wal shm Writer w0 rem1 Reader wem0 4 db wal shm Writer w0 rem1 Reader wem0 5 db wal shm Writer w0 Reader wem0 6 db wal shm Writer w0 Reader wem0 w1 7 db wal shm Writer w0 Reader wem0 w1 wal disk w1 8 db wal shm Writer w0 Reader wem0 w1 wem1 9 db wal shm Writer w0 Reader wem1 w1 wem - writer end-markrem - reader end-mark w - comit-reader -writer WAL - R/W 50
  • 103. 1 Условие чекпоинта выполнено (сразу после COMMIT или вручную) 1 db wal shm Writer w0 Reader wem1 w1 rem2 }CL WAL - checkpoint wem - writer end-markrem - reader end-mark w - comit-reader -writer -checkpoint CL - checkpoint level51
  • 104. 1 Условие чекпоинта выполнено (сразу после COMMIT или вручную) 2 Перенос страниц из конца журнала в базу до первого rem 1 db wal shm Writer w0 Reader wem1 w1 rem2 }CL 2 db wal shm Check point w0 Reader wem1 w1 w1 rem2 WAL - checkpoint wem - writer end-markrem - reader end-mark w - comit-reader -writer -checkpoint CL - checkpoint level51
  • 105. 1 Условие чекпоинта выполнено (сразу после COMMIT или вручную) 2 Перенос страниц из конца журнала в базу до первого rem 3 Запись файла базы на диск 1 db wal shm Writer w0 Reader wem1 w1 rem2 }CL 2 db wal shm Check point w0 Reader wem1 w1 w1 rem2 3 db wal shm Check point w0 Reader wem1 w1 w1 rem2 db disk w1 WAL - checkpoint wem - writer end-markrem - reader end-mark w - comit-reader -writer -checkpoint CL - checkpoint level51
  • 106. 1 Условие чекпоинта выполнено (сразу после COMMIT или вручную) 2 Перенос страниц из конца журнала в базу до первого rem 3 Запись файла базы на диск 4 Обновление в shm последнего комита (wem1). COMMIT 1 db wal shm Writer w0 Reader wem1 w1 rem2 }CL 2 db wal shm Check point w0 Reader wem1 w1 w1 rem2 3 db wal shm Check point w0 Reader wem1 w1 w1 rem2 db disk w1 4 db wal shm Check point w0 Reader wem1 w1 w1 rem2 wem0 WAL - checkpoint wem - writer end-markrem - reader end-mark w - comit-reader -writer -checkpoint CL - checkpoint level51
  • 107. 1 Условие чекпоинта выполнено (сразу после COMMIT или вручную) 2 Перенос страниц из конца журнала в базу до первого rem 3 Запись файла базы на диск 4 Обновление в shm последнего комита (wem1). COMMIT 5 Исходное состояние с изменениями 1 db wal shm Writer w0 Reader wem1 w1 rem2 }CL 2 db wal shm Check point w0 Reader wem1 w1 w1 rem2 3 db wal shm Check point w0 Reader wem1 w1 w1 rem2 db disk w1 4 db wal shm Check point w0 Reader wem1 w1 w1 rem2 wem0 5 db wal shm Check point w0 Reader wem0 w1 rem2 WAL - checkpoint wem - writer end-markrem - reader end-mark w - comit-reader -writer -checkpoint CL - checkpoint level51
  • 108. WAL 52
  • 109. WAL Для ускорения чтения как можно меньший журнал (поиск end-mark зависит от размера) - то есть делать чекпоинты как можно чаще - в идеале каждый комит 53
  • 110. WAL Для ускорения чтения как можно меньший журнал (поиск end-mark зависит от размера) - то есть делать чекпоинты как можно чаще - в идеале каждый комит Для ускорения записи как можно дольше не делать чекпоинт (из-за дополнительного времени на перенос в базу и двойной записи на диск) 53
  • 112. WAL 1 Создаем базу SQLite 2 Меняем режим на WAL 54
  • 113. WAL 1 Создаем базу SQLite 2 Меняем режим на WAL 3 Журнал пустой 54
  • 114. WAL 1 Создаем базу SQLite 2 Меняем режим на WAL 3 Журнал пустой 4 Вносим изменения 54
  • 115. WAL 1 Создаем базу SQLite 2 Меняем режим на WAL 3 Журнал пустой 4 Вносим изменения 5 Журнал активен (данные в журнале, а не в файле базы) 54
  • 116. Индексы и планировщик запросов SQLite Query Planner - ИИ, который выбирает наилучший способ выполнить запрос, и индексы являются его главным инструментом 55
  • 118. Поиск (SELECT) Полное сканирование (Full Table Scan) Полный перебор Поиск по RowID (Lookup By Rowid) Бинарный поиск по таблице 56
  • 119. Поиск (SELECT) Полное сканирование (Full Table Scan) Полный перебор Поиск по RowID (Lookup By Rowid) Бинарный поиск по таблице Поиск по индексу (Lookup By Index) Бинарный поиск по индексу + бинарный поиск по таблице 56
  • 120. Поиск (SELECT) Полное сканирование (Full Table Scan) Полный перебор Поиск по RowID (Lookup By Rowid) Бинарный поиск по таблице Поиск по индексу (Lookup By Index) Бинарный поиск по индексу + бинарный поиск по таблице Покрытие индекса (Covering Indices) Бинарный поиск по индексу 56
  • 121. Сортировка (ORDER BY) Сортировка по значению «Сложная» сортировка 57
  • 122. Сортировка (ORDER BY) Сортировка по значению «Сложная» сортировка Сортировка по RowID Просто вывод 57
  • 123. Сортировка (ORDER BY) Сортировка по значению «Сложная» сортировка Сортировка по RowID Просто вывод Сортировка по индексу «Простая» сортировка 57
  • 124. Сортировка (ORDER BY) Сортировка по значению «Сложная» сортировка Сортировка по RowID Просто вывод Сортировка по индексу «Простая» сортировка Сортировка по покрытому индексу Просто вывод 57
  • 125. Индексы Индекс - упорядоченная таблица, связанная с оригинальной 58
  • 126. Индексы • Замедляют операции изменений за счет переиндексации (REINDEX) Индекс - упорядоченная таблица, связанная с оригинальной 58
  • 127. Индексы • Замедляют операции изменений за счет переиндексации (REINDEX) • Могут быть частичными (Partial) - для определенных строк Индекс - упорядоченная таблица, связанная с оригинальной 58
  • 128. Индексы • Замедляют операции изменений за счет переиндексации (REINDEX) • Могут быть частичными (Partial) - для определенных строк • Могут быть уникальными (UNIQUE) Индекс - упорядоченная таблица, связанная с оригинальной 58
  • 129. Индексы • Замедляют операции изменений за счет переиндексации (REINDEX) • Могут быть частичными (Partial) - для определенных строк • Могут быть уникальными (UNIQUE) • Индекс по умолчанию - RowID Индекс - упорядоченная таблица, связанная с оригинальной 58
  • 130. Индексы Не нужны, когда Мало данных Изменения в таблице происходят намного чаще чем выборки • Замедляют операции изменений за счет переиндексации (REINDEX) • Могут быть частичными (Partial) - для определенных строк • Могут быть уникальными (UNIQUE) • Индекс по умолчанию - RowID Индекс - упорядоченная таблица, связанная с оригинальной 58
  • 131. Индексы Не нужны, когда Мало данных Изменения в таблице происходят намного чаще чем выборки Плохо в качестве индекса, когда Значения поля часто NULL Значения поля часто меняется • Замедляют операции изменений за счет переиндексации (REINDEX) • Могут быть частичными (Partial) - для определенных строк • Могут быть уникальными (UNIQUE) • Индекс по умолчанию - RowID Индекс - упорядоченная таблица, связанная с оригинальной 58
  • 132. Таблицы без ROWID МОГУТ повысить быстродействие и уменьшить размер 59
  • 133. Таблицы без ROWID • Если используются составные первичные ключи • Если первичный ключ - Integer (просто дупликация) • Если не хранятся большие строки или BLOB • В целом - если размер таблиц - небольшой ( < 1/20 страницы ) МОГУТ повысить быстродействие и уменьшить размер 59
  • 134. Таблицы без ROWID • Обязаны иметь первичный ключ! • Автоинкремент не работает • Первичный ключ не может быть NULL • Если используются составные первичные ключи • Если первичный ключ - Integer (просто дупликация) • Если не хранятся большие строки или BLOB • В целом - если размер таблиц - небольшой ( < 1/20 страницы ) sqlite3_analyzer МОГУТ повысить быстродействие и уменьшить размер 59
  • 135. Full Text Search 60 Расширения (модули), позволяющие выполнять эффективный полнотекстовый поиск, путем создания спец виртуальных таблиц
  • 136. Full Text Search 60 Расширения (модули), позволяющие выполнять эффективный полнотекстовый поиск, путем создания спец виртуальных таблиц FTS3, FTS4 подключены по молчанию
  • 137. Full Text Search 60 Расширения (модули), позволяющие выполнять эффективный полнотекстовый поиск, путем создания спец виртуальных таблиц FTS3, FTS4 подключены по молчанию FTS4 более оптимизирована и производительна, но занимает больше места в памяти
  • 138. Full Text Search 60 Расширения (модули), позволяющие выполнять эффективный полнотекстовый поиск, путем создания спец виртуальных таблиц FTS3, FTS4 подключены по молчанию FTS4 более оптимизирована и производительна, но занимает больше места в памяти При поиске для сравнения после WHERE используется терма MATCH
  • 139. FTS - Tokenizer Набор правил для выборки 61
  • 140. FTS - Tokenizer Набор правил для выборки simple (по умолчанию) Добавляет регистронезависимость porter Алгоритм стемминга Портера (упр. - поиск по корню слова) icu Учитывает локаль (пр. - icu uk_UA) кастомный Реализуется используя интерфейс fts3_tokenizer.h stop-word Популярный токенайзер для исключения слов из выборки (FMStopWordTokenizer) 61
  • 141. FTS - использование // 1 столбец - «content» CREATE VIRTUAL TABLE data USING fts4(); // 2 кастомных столбца и токенайзер porter CREATE VIRTUAL TABLE data USING fts4(title, keywords, tokenize=porter); // вирт таблица просто ссылается на реальную CREATE VIRTUAL TABLE IF NOT EXISTS fdocs USING fts4(content="docs", name, tokenize=simple) // запрос SELECT name, composer FROM fdocs WHERE fdocs MATCH ‘nix’» // перестройка fts таблицы (триггеров нет) INSERT INTO fdocs(fdocs) VALUES('rebuild'); // оптимизация* INSERT INTO fdocs(fdocs) VALUES('optimize'); 62
  • 142. JSON1 extension • Сохраняет JSON как обычный текст • Предоставляет функции для работы с JSON • По умолчанию отсутствует • Можно собрать SQLite c DSQLITE_ENABLE_JSON1 Перенос логики JSON обработки на SQLite уровень 63
  • 143. Внешние ключи PRAGMA foreign_keys = ON / OFF(по умолчанию); 64
  • 144. Внешние ключи PRAGMA foreign_keys = ON / OFF(по умолчанию); ON DELETE, ON UPDATE NO ACTION По умолчанию 64
  • 145. Внешние ключи PRAGMA foreign_keys = ON / OFF(по умолчанию); ON DELETE, ON UPDATE NO ACTION По умолчанию RESTRICT Запрещает изменять (удалять) родительский ключ 64
  • 146. Внешние ключи PRAGMA foreign_keys = ON / OFF(по умолчанию); ON DELETE, ON UPDATE NO ACTION По умолчанию RESTRICT Запрещает изменять (удалять) родительский ключ SET NULL Значение дочернего ключа устанавливается в SQL NULL 64
  • 147. Внешние ключи PRAGMA foreign_keys = ON / OFF(по умолчанию); ON DELETE, ON UPDATE NO ACTION По умолчанию RESTRICT Запрещает изменять (удалять) родительский ключ SET NULL Значение дочернего ключа устанавливается в SQL NULL SET DEFAULT Значение дочернего ключа устанавливается в значение по умолчанию 64
  • 148. Внешние ключи PRAGMA foreign_keys = ON / OFF(по умолчанию); ON DELETE, ON UPDATE NO ACTION По умолчанию RESTRICT Запрещает изменять (удалять) родительский ключ SET NULL Значение дочернего ключа устанавливается в SQL NULL SET DEFAULT Значение дочернего ключа устанавливается в значение по умолчанию CASCADE Обновляет значение дочернего ключа или удаляет все строку 64
  • 149. Ограничения внешних ключей immediate При ошибке сразу генерируется исключение (по умолчанию) deferred Исключение не генерируется пока не вызван COMMIT (при явной транзакции!) DEFERRABLE INITIALLY DEFERRED - при описании ключа CREATE TABLE devs( devId INTEGER PRIMARY KEY, devName TEXT ); CREATE TABLE projects( projectId INTEGER, projectName TEXT, projectDev INTEGER, FOREIGN KEY (projectDev) REFERENCES devs(devId) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); BEGIN; INSERT INTO projects VALUES(1, 'TestSQLite', 5); COMMIT; -> SQL error: foreign key constraint failed INSERT INTO devs VALUES(5, 'Marvin’); COMMIT; 65
  • 150. Новый планировщик (NGQP) GGQP (SQLite 3.8) всегда может найти такой же или лучший план ANALYZE собирая статистику, позволяет выбрать лучший план 66
  • 151. Новый планировщик (NGQP) GGQP (SQLite 3.8) всегда может найти такой же или лучший план ANALYZE собирая статистику, позволяет выбрать лучший план SQLite гарантирует «СТАБИЛЬНОСТЬ» Один и тот же план при неизменных условиях: - неизменность схемы, индексов - не использования ANALYZE 66
  • 152. Лучший план (NGQP) 1 Если у вас все в порядке не думайте об этом! 67
  • 153. Лучший план (NGQP) 2 Используйте индексы В большинстве случаев индексы позволяют повысить быстродействие 68
  • 154. Лучший план (NGQP) 2 Используйте индексы В большинстве случаев индексы позволяют повысить быстродействие 3 Не создавайте low-quality индексы Low-quality индексы - которые повторяются 10-20 и более раз. Также, когда значение индекса - enum, bool 68
  • 155. Лучший план (NGQP) 2 Используйте индексы В большинстве случаев индексы позволяют повысить быстродействие 3 Не создавайте low-quality индексы Low-quality индексы - которые повторяются 10-20 и более раз. Также, когда значение индекса - enum, bool 4 Если таки используете low- quality индексы - запускайте ANALYZE ANALYZE sqlite_master вначале использования позволит собирать статистику 68
  • 156. Лучший план (NGQP) 2 Используйте индексы В большинстве случаев индексы позволяют повысить быстродействие 3 Не создавайте low-quality индексы Low-quality индексы - которые повторяются 10-20 и более раз. Также, когда значение индекса - enum, bool 4 Если таки используете low- quality индексы - запускайте ANALYZE ANALYZE sqlite_master вначале использования позволит собирать статистику 5 Используйте инструменты Измеряйте! 68
  • 157. Лучший план (NGQP) 2 Используйте индексы В большинстве случаев индексы позволяют повысить быстродействие 3 Не создавайте low-quality индексы Low-quality индексы - которые повторяются 10-20 и более раз. Также, когда значение индекса - enum, bool 4 Если таки используете low- quality индексы - запускайте ANALYZE ANALYZE sqlite_master вначале использования позволит собирать статистику 5 Используйте инструменты Измеряйте! 6 Специальные решения и функции - последний довод INDEXED BY, unary «+», unlikely() и др. - могут оказаться преждевременной оптимизацией ! 68
  • 158. 69
  • 159. Куда бежать, если заказчик просит «потюнить» базу? Code should run as faster as necessary, but no faster. Richard E. Pattis 70
  • 160. Локализация проблемы в приложении • Архитектура • Логические ошибки и/или неправильное использование • Профайлинг 71
  • 163. VACUUM Перестраивает файл базы - аналог дефрагментации 74
  • 164. VACUUM Перестраивает файл базы - аналог дефрагментации Во время вакумирования, копирует весь контент во временную базу, после чего перезаписывает оригинальный файл. Размер занимаемого пространства увеличивается вдвое 74
  • 165. VACUUM Перестраивает файл базы - аналог дефрагментации Во время вакумирования, копирует весь контент во временную базу, после чего перезаписывает оригинальный файл. Размер занимаемого пространства увеличивается вдвое Может изменить RowID, если они нигде явно не используются 74
  • 166. VACUUM Перестраивает файл базы - аналог дефрагментации Во время вакумирования, копирует весь контент во временную базу, после чего перезаписывает оригинальный файл. Размер занимаемого пространства увеличивается вдвое Может изменить RowID, если они нигде явно не используются Не выполнится, если происходит транзакция 74
  • 167. VACUUM Перестраивает файл базы - аналог дефрагментации Во время вакумирования, копирует весь контент во временную базу, после чего перезаписывает оригинальный файл. Размер занимаемого пространства увеличивается вдвое Может изменить RowID, если они нигде явно не используются Не выполнится, если происходит транзакция Для WAL ничего не произойдет ( 74
  • 168. pragma auto_vacuum NONE (0) (по умолчанию) Задается на этапе компиляции SQLITE_DEFAULT_AUTOVACUUM. FULL (1) Выполняется при каждом комите. INCREMENTAL (2) Используется вместе с pragma incremental_vacuum(N) N - количество страниц необходимых для выполнения Не является VACUUM в автоматическом режиме ! Пустые страницы перемещаются в конец файла и затем файл базы обрезается. Для смены режима по умолчанию нужно выполнить настоящий VACUUM 75
  • 172. Progress handling sqlite3_progress_handler(sqlite3* D, int N, int(*X)(void*), void* P); 77
  • 173. Progress handling sqlite3_progress_handler(sqlite3* D, int N, int(*X)(void*), void* P); D Соединение N Скважность - количество машинных инструкций относительно вызова каллбека X Каллбек. Установка в NULL или возврат каллбека < 1 - отключает обработчик P Передаваемый параметр 77
  • 174. Trace hook int sqlite3_trace_v2(sqlite3* D, unsigned M, int(*X)(unsigned TC,void* CC,void* PP,void* XP), void *P); 78
  • 175. Trace hook int sqlite3_trace_v2(sqlite3* D, unsigned M, int(*X)(unsigned TC,void* CC,void* PP,void* XP), void *P); D Соединение M SQLITE_TRACE_STMT Когда готово и запускается выражение (sqlite3_stmt) SQLITE_TRACE_PROFILE На каждом шаге выполнения (sqlite3_step) SQLITE_TRACE_ROW Когда создается строка вывода (SELECT) SQLITE_TRACE_CLOSE Когда закрывается соединение X Каллбек P Передаваемый параметр 78
  • 176. Trace hook callback int(*X)(unsigned T,void* C,void* P,void* X) T SQLITE_TRACE_STMT SQLITE_TRACE_PROFILE SQLITE_TRACE_ROW SQLITE_TRACE_CLOSE C Передаваемый параметр P sqlite3_stmt sqlite3 X «SQL» длительность, ns - 79
  • 182. Попытка оптимизировать базу Фактически выполняет ANALYZE для таблиц* pragma OPTIMIZE 81
  • 183. Попытка оптимизировать базу Фактически выполняет ANALYZE для таблиц* Вызывать перед каждым закрытием соединения или же через каждые 2 часа для длительных соединений pragma OPTIMIZE SQLite советует: 81
  • 184. Explain query EXPLAIN QUERY PLAN + «SQL» DEBUG only! Показывает используемый план (NGQP) 82
  • 185. Explain query - результат select id уровень вложенности запроса order порядок сортировки from позиция в FROM выражении для каждого SELECT совпадения (имеет смысл для многотабличных запросов) detail SCAN • имя таблицы • использование индексов (автоиндексы) • покрытие индекса • какое выражение WHERE используется для индекса SEARCH 83
  • 186. Explain query - результат select id уровень вложенности запроса order порядок сортировки from позиция в FROM выражении для каждого SELECT совпадения (имеет смысл для многотабличных запросов) detail SCAN • имя таблицы • использование индексов (автоиндексы) • покрытие индекса • какое выражение WHERE используется для индекса SEARCH SCAN Полный перебор, медленно 83
  • 187. Explain query - результат select id уровень вложенности запроса order порядок сортировки from позиция в FROM выражении для каждого SELECT совпадения (имеет смысл для многотабличных запросов) detail SCAN • имя таблицы • использование индексов (автоиндексы) • покрытие индекса • какое выражение WHERE используется для индекса SEARCH SCAN Полный перебор, медленно SEARCH USING INDEX Используется индекс, но данные в оригинальной таблице, хорошо 83
  • 188. Explain query - результат select id уровень вложенности запроса order порядок сортировки from позиция в FROM выражении для каждого SELECT совпадения (имеет смысл для многотабличных запросов) detail SCAN • имя таблицы • использование индексов (автоиндексы) • покрытие индекса • какое выражение WHERE используется для индекса SEARCH SCAN Полный перебор, медленно SEARCH USING INDEX Используется индекс, но данные в оригинальной таблице, хорошо SEARCH USING COVERING INDEX Данные уже в таблице с индексом, максимально быстро 83
  • 189. Explain query - результат select id уровень вложенности запроса order порядок сортировки from позиция в FROM выражении для каждого SELECT совпадения (имеет смысл для многотабличных запросов) detail SCAN • имя таблицы • использование индексов (автоиндексы) • покрытие индекса • какое выражение WHERE используется для индекса SEARCH SCAN Полный перебор, медленно SEARCH USING INDEX Используется индекс, но данные в оригинальной таблице, хорошо SEARCH USING COVERING INDEX Данные уже в таблице с индексом, максимально быстро USE TEMP B-TREE Пост обработка (пр. - group by), обычно медленно - лучше сделать индекс 83
  • 190. Analyzer sqlite3_analyzer - утилита, показывает как много и эффективно используется пространство таблицами и индексами в файле базы 84
  • 191. Analyzer sqlite3_analyzer - утилита, показывает как много и эффективно используется пространство таблицами и индексами в файле базы 84
  • 192. Оптимизация размеров Страницы pragma page_size = bytes Кеша pragma cache_size = kbytes 85
  • 193. ДБ Профайлер • Профайлер собирает информацию по калбекам запрошенных данных (тип запроса, жизненный цикл) • Отправляются сигналы для использования в Instruments (Points of Interests) • Вывод данных реализован в виде графиков Хочется - [FMDatabase startProfile]; [FMDatabase stopProfile]; Подключение через категорию FMDatabase, где свайзлится на класс наследника и переопределяются методы выполнения 86
  • 194. Пример - ДБ Профайлер 87
  • 195. ДБ Профайлер + Instruments Можно настроить для отображения типов запросов (SELECT, INSERT …) 88
  • 199. FMDatabase FMDatabase Враппер соединения к SQLite базе FMDatabaseQueue Сериальная очередь выполнения запросов к базе - на одном соединении в одном потоке 91
  • 202. SQLite optimization FAQ H T T P : / / C O D I F I C A R . C O M . B R / B L O G / S Q L I T E - O P T I M I Z AT I O N - FA Q / 94
  • 204. SQLite чеклист Поиск главных вопросов 1 Режим доступа 95
  • 205. SQLite чеклист Поиск главных вопросов 1 2 Способ использования Режим доступа 95
  • 206. SQLite чеклист Поиск главных вопросов 1 2 Способ использования Режим доступа 95
  • 209. VACUUM OPTIMAZE (ANALIZE) 1 Смешанный режим R/W ДаНетROLLBACK WAL MultiConnection Multi-threading Busy Handlers* Интенсивное использование ДаНет SingleConnection Single-threading Кастомные схемы доступа 96
  • 210. VACUUM OPTIMAZE (ANALIZE) 1 Смешанный режим R/W ДаНетROLLBACK WAL MultiConnection Multi-threading Busy Handlers* Интенсивное использование ДаНет SingleConnection Single-threading Кастомные схемы доступа FMDatabaseQueue FMDatabase2 96
  • 212. Trace Explain query Есть явные проблемы в конкретных запросах ? Да Нет, но все плохо Нет, все супер 2 97
  • 213. Trace Explain query Есть явные проблемы в конкретных запросах ? Да Нет, но все плохо Используем индексы, запросы и транзакции, FK, WithoutRowId, SQL, FTS … Не помогло / Хочу еще ? Да Нет, доволен Меняем логику (место) работы, архитектуру (нормализация и де…, запросы и транзакции …) Нет, все супер 2 97
  • 214. Trace Explain query Есть явные проблемы в конкретных запросах ? Да Нет, но все плохо Используем индексы, запросы и транзакции, FK, WithoutRowId, SQL, FTS … Не помогло / Хочу еще ? Да Нет, доволен Меняем логику (место) работы, архитектуру (нормализация и де…, запросы и транзакции …) Режимы журналов Auto/manual checkpoint Shared Cache Page size Amalgamation … Нет, все супер 2 1 97
  • 215. 98