Набор данных, выводимый командой EXPLAIN, содержит детальную информацию о ходе выполнения запроса. Каждая строка в этом наборе описывает одну из операций, составляющих запрос. Например, команда
EXPLAIN SELECT name,address,product_id,qty FROM Customers, Orders WHERE Customers.id=customer_id AND date='20007-12-12';
выводит результат, представленный в табл. 6.1. Таблица 6.1. Результат выполнения команды EXPLAIN
Столбец table (таблица) содержит имя обрабатываемой таблицы, а столбец select_type (тип запроса) указывает место операции в структуре запроса: • SIMPLE – простой запрос без вложенных запросов и UNION; • PRIMARY – первый запрос в UNION или внешний запрос, имеющий вложенные запросы; • UNION – второй и последующие запросы в объединении UNION; • DEPENDENT UNION – второй и последующие вложенные запросы в объединении UNION, связанные с внешним запросом (о связанных подзапросах вы узнали в подразделе «Операторы сравнения с результатами вложенного запроса»); • UNION RESULT – операция объединения результатов запросов; • SUBQUERY – вложенный запрос; • DEPENDENT SUBQUERY, UNCACHEABLE SUBQUERY – вложенный запрос, связанный с внешним запросом; • DERIVED – запрос, генерирующий промежуточный результат (такой запрос следует после ключевого слова FROM).
ROW_FORMAT <Формат> Данный параметр определяет формат таблицы. Таблица с типом InnoDB может иметь формат COMPACT или REDUNDANT. Формат COMPACT используется по умолчанию и является оптимальным. Для таблицы с типом MyISAM вы можете указать значение FIXED (статический формат) или DYNAMIC (динамический формат). Обратите внимание, что статический формат нельзя установить для таблицы, содержащей столбцы с типом TINYBLOB, TINYTEXT, BLOB, TEXT, MEDIUMBLOB, MEDIUMTEXT, LONGBLOB и LONGTEXT: если вы укажете для такой таблицы статический формат, он автоматически изменится на динамический. Примечание Проверить, какие форматы были фактически присвоены таблицам, вы можете с помощью команды SHOW TABLE STATUS; Эта команда выводит информацию обо всех таблицах в текущей базе данных. В столбце Row_format вы увидите текущий формат таблицы. Если вы приняли все необходимые меры для улучшения структуры таблиц, но запросы все равно выполняются медленно, попытаемся сделать более эффективными сами запросы
• DELAY_KEY_WRITE 1. Задание этого параметра для таблиц MyISAM включает режим отложенной записи на диск буфера индексов. Этот режим позволяет ускорить обновление индексов при добавлении и изменении записей благодаря более редкому обращению к диску. • PACK_KEYS <0, 1 или DEFAULT>. Данный параметр для таблиц MyISAM определяет режим сжатия индексов. Значение 1 указывает, что сжатие будет использоваться как для символьных, так и для числовых индексов. Это ускоряет поиск по таблице, но замедляет обновление индексов. Сжатие числовых индексов дает наибольший эффект в случае большого количества повторяющихся чисел. Значение DEFAULT указывает, что уплотняться будут только символьные индексы, а значение 0 полностью отключает сжатие
Наконец, для повышения производительности таблиц вы можете использовать следующие опциональные свойства таблицы: • AVG_ROW_LENGTH <Размер в байтах>, MAX ROWS <Количество строк>. С помощью этих свойств вы можете задать, соответственно, предполагаемую среднюю длину строки таблицы и предполагаемое максимальное количество строк в таблице. Эти параметры полезно указать для больших динамических таблиц MyISAM: они помогут программе MySQL определить размер таблицы, а следовательно, выбрать оптимальную длину индексов
Более короткие индексы работают быстрее. Поэтому в качестве первичного ключа таблицы целесообразно использовать целочисленный столбец с наименьшим размером. При создании индекса для символьного столбца полезно ограничить длину индекса, включив в него только начальные подстроки значений (см. пункт «Ключевые столбцы и индексы»); количество индексируемых символов желательно подобрать так, чтобы минимизировать количество строк с одинаковой начальной подстрокой.
Для максимально эффективного использования индексов необходимо учитывать следующие факты. • Индекс замедляет добавление и обновление строк таблицы. Поэтому рекомендуется создавать только те индексы, которые будут использоваться в часто выполняемых запросах. • Для поиска с условиями на значение нескольких столбцов лучше всего подходит многостолбцовый индекс. Если же в таблице есть только отдельные индексы для каждого столбца, то будет использован лишь один из них, в наибольшей степени сужающий круг подходящих записей. При создании индекса для группы столбцов важно правильно выбрать последовательность столбцов в индексе, так как в запросах может применятьсячастьмногостолбцового индекса, состоящая из несколькихначальных столбцов. Например, если в таблицу Orders (Заказы) добавить индекс
INDEX (date,product_id,customer_id)
то он ускорит выполнение запросов
SELECT * FROM Orders WHERE date=CURDATE(); SELECT * FROM Orders WHERE date=CURDATE() AND product_id=3;
но будет бесполезен при выполнении запросов
SELECT * FROM Orders WHERE product_id=3; SELECT * FROM Orders WHERE product_id=3 AND customer_id=533;
Если вы все же используете динамические таблицы MyISAM, необходимо учитывать, что изменение данных в такой таблице может привести к еефрагментации.Так, если значение в символьном столбце заменяется более длинным, то строка таблицы разделяется на две (или более) части, которые хранятся отдельно друг от друга. Фрагментация сказывается на скорости доступа к данным, поэтому динамическую таблицу рекомендуется время от времени (в зависимости от интенсивности изменений) дефрагментировать с помощью команды
Указание свойства NOT NULL для всех столбцов, для которых это возможно. Если в столбце не предполагается использовать неопределенные значения, задание свойства NOT NULL позволит уменьшить длину каждого значения на 1 бит. Исключением из правила минимизации объема данных является использование статического формата таблиц. Другими словами, если в таблице с типом MyISAM отсутствуют символьные столбцы, допускающие значения переменной длины (такие как VARCHAR, TEXT, BLOB и т. п.), то такая таблица по умолчанию сохраняется в статическом формате; если же в таблице есть столбцы с переменной длиной значений, то по умолчанию применяется динамический формат. Как правило, динамические таблицы занимают значительно меньше места, чем статические, однако статические таблицы работают намного быстрее
• Подбор типов столбцов с наименьшим размером. Например, если значения в целочисленном столбце не могут превышать 10 000, целесообразно объявить его как SMALLINT, а не INT или MEDIUMINT. Определить диапазон возможных значений столбца вы можете с помощью запроса
SELECT <Список столбцов> FROM <Имя таблицы> PROCEDURE ANALYSE();
Выполнив этот запрос после загрузки данных в таблицу, вы узнаете максимальное значение числового столбца, максимальную длину символьного столбца, количество неопределенных значений в столбце и многое другое.