Для получения конкретной помощи по SQLite и / или iOS, вот некоторые ресурсы, которые, кажется, дают действительно хороший совет.
Теперь, в более общем смысле, чтобы действительно выполнить настройку производительности для любой системы баз данных предприятия, вот области, которые я считаю важными, которые вам необходимо понять:
Базовая логическая архитектура хранения данных системы, с которой вы работаете. Например, b-дерево, экстент, страница, размеры и конфигурации, количество данных, считываемых за раз, максимальный размер строки (если это проблема в вашей СУБД), что делается с данные (опять же, если это проблема в вашей СУБД).
Индексы, ограничения и базовый порядок таблиц и данных строк: кучи, кластеризованные, некластеризованные, уникальные и неединственные значения этих индексов, первичные ключи, уникальные ограничения, включенные столбцы. Во всех этих индексах разрешены ли пустые значения, разрешен только один нулевой или нет. Uniqueifiers. Индекс покрытия.
SARGability (ищите SARG, что сокращенно от "Search ARGument").
Внешние ключи, значения по умолчанию, каскадное удаление / обновление, их влияние на вставки и удаления.
Требуется ли для NULL какое-либо место для хранения и зависит ли это от положения столбца. Количество байтов, необходимое для хранения каждого типа данных. Когда конечные пробелы хранятся или не сохраняются для строковых типов данных. Упакованные и неупакованные типы данных (например, число с плавающей запятой и десятичное число против целого числа). Концепция строк на странице (или наименьшая единица чтения с диска) в кластеризованных и некластеризованных индексах.
Коэффициент заполнения, фрагментация, статистика, селективность индекса, разбиение страниц, указатели переадресации.
При «группировании» операция может повысить производительность, и почему, и как сделать это наиболее эффективно.
СОЕДИНЕНИЯ ВНУТРЕННИХ, ЛЕВЫХ, ПРАВИЛЬНЫХ, ПОЛНЫХ И КРЕСТНЫХ. Полу-соединения (СУЩЕСТВУЕТ) и анти-полусоединения (НЕ СУЩЕСТВУЕТ). Любой другой специфичный для языка синтаксис, такой как ИСПОЛЬЗОВАНИЕ в mySql и CROSS APPLY / OUTER APPLY в SQL Server. Эффект от наложения условия соединения в предложении ON внешнего соединения против наложения его в предложении WHERE.
Независимые подзапросы, коррелированные подзапросы, производные таблицы, общие табличные выражения, понимание того, что EXISTS и NOT EXISTS обычно представляют коррелированный подзапрос, но обычно рассматриваются в плане выполнения как объединения (полу или анти-полу соединения ).
Просмотр и понимание планов выполнения в графическом или текстовом виде. Просмотр статистики / профиля ЦП, операций чтения, записи и длительности, используемых целыми пакетами SQL или отдельными операторами. Понимание ограничений планов выполнения и профилей, что практически означает, что вам, как правило, приходится использовать оба варианта для хорошей оптимизации. Кеширование и повторное использование планов выполнения, истечение срока действия планов из кеша. Измерение параметров и параметризация. Динамический SQL по отношению к ним.
Относительные затраты на преобразование типов данных в другие типы данных или просто работу с этими типами данных. (Например, твердое эмпирическое правило заключается в том, что работа со строками обходится дороже, чем работа с числами.)
Обычно непомерные затраты на построчную обработку, а не на основе множеств.Правильное использование курсоров (редко, хотя иногда требуется).Как функции могут скрывать затраты плана выполнения.Заманчивая ловушка написания функций, которые вызываются для каждой строки, когда проблема может быть решена в наборах (хотя это может быть непросто научиться видеть, особенно потому, что традиционное программирование приложений имеет тенденцию обучать людей мыслить в терминах подобных функций),
Поиск, сканирование, сканирование диапазона, сканирование с пропуском.Поиск по закладкам, то есть поиск по индексу с последующим поиском по таблице в той же таблице с использованием значения, найденного при поиске по индексу.Цикл, слияние и хеш-соединение.Стремительные и ленивые катушки.Присоединяйтесь к заказу.Расчетное количество строк.Фактическое количество строк.
Когда запрос слишком большой и должен быть разбит на несколько, с использованием временных таблиц или других средств.
Многопроцессорные возможности, преимущества и недостатки параллельного выполнения.
Tempdb или другое использование временного файла.Время жизни и область применения временных таблиц, табличных переменных (если таковая имеется в вашей базе данных).Независимо от того, собирается ли статистика для них (во временных таблицах SQL Server используется статистика, а в переменных таблицы нет.)
Блокировка, гранулярность блокировок, типы блокировок, повышение блокировок, блоки, взаимоблокировки.Шаблон доступа к данным (например, сначала UPDATE, затем INSERT, затем DELETE).Намеренные, общие, эксклюзивные замки.Подсказки по блокировке (например, в SQL Server UPDLOCK, HOLDLOCK, READPAST, TABLOCKX).
Транзакции и изоляция транзакций.Чтение зафиксированного, чтение незафиксированного, повторяемое чтение, сериализация, снимок, другие, которые я сейчас не помню.
Файлы данных, файловые группы, отдельные диски, журналы транзакций, простое восстановление, полное восстановлениеСамая старая открытая транзакция или минимальный порядковый номер журнала (LSN), рост файла.
Последовательности, массивы, списки, столбцы идентификаторов, функции управления окнами, TOP / rownum / ограничение числа возвращаемых строк.
Материализованные представления или индексированные представления.Вычисляемые столбцы.
1 к 1, 1 к 0 или 1, 1 ко многим, много ко многим.
UNION, UNION ALL,и другие "вертикальные" соединения.SQL Server также имеет ИСКЛЮЧЕНИЕ и ИНТЕРСЕКТ.
Расширение списков IN () до ИЛИ.Расширение IsNull (), Coalesce () или других механизмов обработки нулей в операторы CASE.
Подводные камни использования DISTINCT для «исправления» запроса вместо решения основной проблемы.
То, как связанные серверы не очень хорошо соединяются по ссылке, запросы к связанному серверу часто становятся построчными, большие объемы данных могут передаваться по ссылке для выполненияобъединение локально, даже если это не имеет смысла.
Подводный камень выполнения любых операций ввода-вывода или ошибок в триггере.Область действия триггеров (независимо от того, срабатывают они для каждой строки или один раз для каждой операции с данными).
Заставить клиентский интерфейс, графический интерфейс, инструмент создания отчетов или другой клиент выполнять работу по типу клиента(например, форматирование дат или чисел в виде строк) вместо механизма БД.
Обработка ошибок.Откат транзакций и то, как всегда выполняется откат к первой транзакции, независимо от того, насколько глубоко они вложены, но COMMIT фиксирует только один уровень работы.
Большинство из них имеют некоторое отношение к производительности.,Некоторые из них менее важны для производительности, но (на мой взгляд) важны, если вы хотите быть хорошим разработчиком SQL, потому что недостаточно просто иметь быстрые запросы, они также должны быть правильными, хорошо играть с другими и иметь дело снеисправности правильно.Если вы продолжаете писать SQL профессионально и хотите улучшить его, то вам, в конечном счете, нужно будет знать большинство этих вещей.Я бы начал с понимания организации таблиц, индексов, поиска и сканирования, а также соединений hash / merge / loop.Я не знаю много о SQLite, но эти вещи глобальны для любой СУБД.
Одна вещь, которая может вам очень помочь, - это распознавание, когда запросы включают поиск данных, как если бы вы искали имена, адреса, номера телефонов и другие вещи в большой телефонной книге или серии телефонных книг, имеющих различные индексы. сзади. Возможно, существует обратный индекс номера телефона или индекс, организованный по имени. Продумывание путей наименьшего количества работы / кратчайшего времени для получения информации от этих физических объектов поможет вам понять, какова задача механизма запросов при выборе плана выполнения. Это понимание поможет вам сказать что-то вроде: «подождите минутку, почему он выполняет сканирование, когда должен выполнять поиск? Эта таблица очень большая и имеет индекс по X!»
Пример сценария: телефонная книга организована как обычно по фамилии. У вас также есть индекс в конце с только имя и фамилия, отсортированные по имени.
Задание 1: вам нужно записать все номера телефонов каждого человека с именем Торстейна. Лучший план: посмотрите в индекс имени, чтобы найти фамилии 5 человек, имеющих это имя, затем найдите эти фамилии в основной телефонной книге. Вы только что осуществили поиск по некластерному индексу с поиском по закладке по кластерному индексу.
Задача 2: вам нужно записать все телефонные номера каждого человека, чьи имена начинаются с буквы A. Быстро понимая, что нет смысла даже обращаться к указателю имени, вы переходите к основной телефонной книге и просто читать каждую страницу, начиная со страницы 1. Вы только что просмотрели таблицу.
В выборе хорошего «плана выполнения» для этих двух задач (что мы и сделали) есть знание предметной области, которым вы обладаете: вы знаете, что Торстейн - очень редкое имя, и, вероятно, существуют десятки тысяч люди, чье имя начинается с A. Это знание предметной области эквивалентно тому, что статистика предоставляет для механизма запросов. Без статистики плохой план исполнения может быть выбран.
Хотя эти общие советы могут не все применяться в случае SQLite на iPhone, понимание этих концепций действительно поможет вам в работе с базой данных SQLite. Существуют определенные принципы, которые должны быть глобальными, независимо от того, с какой системой вы работаете (например, понимание индексов никогда не будет напрасным усилием, так как любая система, у которой нет индексов, вероятно, не стоит использовать).
Надеюсь, это поможет. Не стесняйтесь просить разъяснений по любому вопросу. Если у вас возникнут проблемы с поиском ресурса, спросите, и я посмотрю, на что я могу вам указать.