Восстанавливать отдельные таблицы сложней. Если для восстановления применяется файл архива, созданный утилитой mysqldump и содержащий данные для множества таблиц, администратору придется извлечь из него строки, соответствующие требуемой таблице, и использовать их в качестве ввода для mysql. Это самая легкая часть процедуры восстановления. После нее необходимо из журнала обновлений извлечь записи, соответствующие требуемой таблице. Для выполнения этой процедуры весьма полезной может оказаться утилита mysqlfindrows, возможности которой позволяют извлекать многострочные запросы из журнала обновлений. Еще один вариант — восстановить всю базу данных на другом сервере, а затем скопировать нужную таблицу в исходную базу данных. Эта процедура гораздо проще! Необходимо лишь убедиться, что работа сервера с исходной базой данных приостановлена в процессе копирования файлов в исходную базу.
Оптимизация — это процесс тонкой настройки системы, направленный на повышение скорости ее работы или сокращение объема используемой памяти. В первой части лекции объясняется, когда и как нужно оптимизировать базы данных. Бинарные дистрибутивы, доступные на Web-узле MySQL, оптимизированы для общего применения. Чтобы адаптировать программу к каким-то специфическим требованиям, ее необходимо перекомпилировать. Об этом и пойдет речь в конце лекции.
Предварительные действия
Перед началом проектирования базы данных поставьте себе задачу добиться максимальной ясности спецификации, даже если на это уйдет больше времени. Помните о том, что услуги программистов стоят дорого, особенно если им приходится разбираться с малопонятным проектом. Простое решение обычно является наилучшим.
Перенося базу данных в производственную среду, позаботьтесь о том, чтобы производительность базы данных была адекватной. Если к проекту прилагается формальная спецификация требований, просмотрите, указываются ли в ней какие-либо ограничения производительности. Для приложений, работающих с базами данных, нередко задается максимальное время выполнения запросов. Продолжительность времени между вводом инструкции и получением результатов запроса зависит от многих факторов. Необходимо заранее учесть те факторы, которые впоследствии нельзя будет контролировать.
Если обнаруживается, что система требует оптимизации, в первую очередь подумайте об обновлении аппаратной части. Это может оказаться самым дешевым вариантом. В 1965 г. Гордон Мур (Gordon Moore) установил, что вычислительные мощности удваиваются каждые 18 месяцев. Данное правило называют законом Мура. Но, несмотря на столь стремительный рост производительности, удельная стоимость вычислительных средств неуклонно снижается. Например, центральные процессоры за полтора года удвоят тактовую частоту, хотя стоить будут так же, как и полтора года назад. Таким образом, обновление компьютера может обойтись дешевле, чем оптимизацияпроекта. Во вторую очередь стоит подумать об обновлении программного обеспечения. Основной программный компонент— это операционная система. Известно, что Linux и BSD UNIX позволяют повысить производительность старых компьютеров, превосходя в этом отношении коммерческие операционные системы, такие, как Windows, особенно если бессбойная работа сервера очень важна.
Обновляется и сама программа MySQL. Когда появится новая версия, ее производительность будет повышена в сравнении с текущей. Но и в текущую версию регулярно вносят мелкие исправления, так что желательно идти в ногу со временем. Основная причина оптимизации — желание сэкономить деньги (оставим в стороне личное удовлетворение и другие причины). Не забывайте об этом в своих попытках повысить производительность программы. Нет смысла затрачивать на оптимизацию больше денег, чем она способна принести. Стоит потрудиться над такой программой, с которой работает множество людей, особенно если это коммерческое приложение. Что касается программ с открытыми кодами, то важность оптимизации здесь трудно определить. Лично я рассматриваю работу над такими проектами как хобби.
Чтобы процесс оптимизации был максимально эффективным, сосредоточьте усилия на самой медленной части программы, улучшение которой обеспечит наибольшую отдачу. Обычно пытаются найти более быстрые альтернативы применяемым алгоритмам. В вычислительной технике относительная эффективность алгоритма записывается в нотации "большого О". Например, запись О(n) означает, что время выполнения алгоритма пропорционально числу обрабатываемых элементов п. Алгоритм типа О(n) является очень медленным. Проанализируйте используемые в программе алгоритмы и подумайте, что можно сделать для их улучшения.
Тесты производительности
Прежде чем приступать к оптимизации, нужно вооружиться средствами измерения производительности. Предусмотрительные разработчики MySQL написали группу Perl сценариев, предназначенных для тестирования производительности MySQL и других СУБД. Эти сценарии расположены в каталоге sql-bench исходного дистрибутива. В подкаталоге Results находятся результаты множества тестов существующих систем, которые можно сравнить с собственными оценками.
В сценариях используется демонстрационная база данных, в которой выполняется восемь различных тестов. Эта база данных называется test и инсталлируется вместе с MySQL. Сценарий run_all_tests запускает все тесты последовательно. При наличии опции -log результаты работы сценария будут сохранены в каталоге output для последующего просмотра. Ниже приведена команда, запускающая тесты из каталога sql-bench.
#./run-all-tests –user=leon –password=secret --leon
Для работы этого сценария необходимо наличие в системе интерпретатора Perl и модуля DBI. Для экспериментов я использую старый компьютер Pentium с частотой 100 МГц, работающий под управлением RedHat Linux. Несмотря на слабую вычислительную мощность, программа MySQL демонстрирует на нем вполне приемлемую производительность. Кроме того, ограниченные возможности системы позволяют быстро выявлять неэффективные программные решения. Результаты тестов, полученные на этом компьютере, показаны в листинге 10.1. Несложно убедиться, что моя система работает примерно в 10 раз медленнее, чем самая медленная из систем, результаты тестов которых имеются в каталоге Results. Если бы такую производительность продемонстрировал рабочийсервер, нужно было бы немедленно обновить его аппаратную часть.
The result logs which were found and the options: 1 mysql-linux 2.2.16_22_i586 MySQL 3.23.39
===============================================================
Operation | 1|
| mysql-l|
-----------------------------------------------------------
Results per test in seconds: | |
-----------------------------------------------------------
ATIS | 549.00|
Alter-table | 4836.00|
Big-tables | 270.00|
Connect | 607.00|
Create | 2027.00|
Insert | +88846.00|
Select | +18339.00|
wisconsin | 135.00|
-----------------------------------------------------------
Листинг 10.1. (html, txt)
The results per operation:
--------------------------------------------------------
alter table add (992) | 2670.00|
alter table drop (496) | 2066.00|
connect (10000) | 95.00|
connect select 1 row (10000) | 115.00|
connect select simple (10000) | 106.00|
count (100) | 364.00|
count distinct (1000) | +779.00|
count distinct 2 (1000) | +605.00|
count distinct big (120) | 1185.00|
count distinct group (1000) | +726.00|
count distinct group on key (1000) | +716.00|
count distinct group on key parts (1) | +708.00|
count distinct key prefix (1000) | +671.00|
count group on key parts (1000) | 706.00|
count on key (50100) | +7005.00|
create + drop (10000) | 109.00|
create MANY tables (10000) | 1196.00|
create index (8) | 52.00|
create key drop (10000) | 115.00|
create table (31) | 0.00|
delete all (12) | 219.00|
delete all many keys (1) | 8960.00|
delete big (1) | 5.00|
delete big many keys (128) | 8956.00|
delete key (10000) | 145.00|
drop index (8) | 47.00|
drop table (28) | 0.00|
drop table when MANY tables (10000) | 105.00|
insert (350768) | 1044.00|
insert duplicate (100000) | 211.00|
insert (100000) | 17849.00|
insert many fields (2000) | 97.00|
insert select 1 key (1) | 102.00|
insert select 2 keys (1) | 125.00|
min max (60) | 301.00|
min max on key (85000) | +2627.00|
multiple value insert (100000) | 102.00|
order by big (10) | 560.00|
order by big key (10) | 503.00|
order by big key2 (10) | 479.00|
order by big key desc (10) | 531.00|
order by big key diff (10) | 586.00|
order by big key prefix (10) | 487.00|
order by key2 diff (500) | 57.00|
order by key prefix (500) | 31.00|
outer join (10) | 989.00|
outer join found (10) | 918.00|
outer join not found (500) | +36000.00|
outer join on key (10) | 810.00|
select 1 row (10000) | 17.00|
select 2 rows (10000) | 23.00|
select big (10080) | 700.00|
select column + column (10000) | 24.00|
select diff key (500) | +1470.00|
select distinct (800) | 145.00|
select group (2925) | +896.00|
select group when MANY tables (10000) | 502.00|
select join (100) | 25.00|
select key (200000) | +1123.00|
select key2 (200000) | +1213.00|
select key2 return key (200000) | +1174.00|
select key2 return prim (200000) | +1197.00|
select key prefix (200000) | +1245.00|
select key prefix join (100) | 197.00|
select key return key (200000) | +1106.00|
select key many fields (2000) | 172.00|
select query cache (10000) | 1075.00|
select query cache2 (10000) | 1075.00|
select range (410) | +1812.00|
select range key2 (25010) | 185.00|
select range prefix (25010) | 197.00|
select simple (10000) | 11.00|
select simple join (500) | 20.00|
update big (10) | 440.00|
update of key (40000) | 627.00|
update of key big (501) | 351.00|
update of primary key many keys(256) | 3290.00|
update with key (300000) | 1011.00|
update with key prefix (100000) | 290.00|
wisc benchmark (114) | 44.00|
--------------------------------------------------------
TOTALS | +124540.00|
--------------------------------------------------------
Листинг 10.2. (html, txt)
Сценарий compare results суммирует и сравнивает результаты тестов. Влистинге 10.1 приведен лишь один набор результатов. В действительности я немного сократил выходные данные, удалив ряд малозначащих пояснений. В первом блоке чисел указано время выполнения каждого из восьми тестов в секундах. Во втором блоке отображается статистика отдельных операций по всем тестам. Числа со знаком "плюс" — это приблизительные оценки, полученные для тестов, время выполнения которых превысило максимум.
Результаты тестов, предоставляемые разработчиками MySQL, можно использовать для выбора аппаратной платформы и операционной системы. На Web узле MySQL (http://www.mysql.com) постоянно публикуются обновляемые результаты и графики сравнения показателей MySQL с показателями других СУБД, работающих на идентичном оборудовании. Приводятся также данные, касающиеся работы MySQL на разных платформах.
Конечно, все эти тесты отражают лишь относительную производительностьсервера. С их помощью можно узнать, насколько возрастет скорость его работы при изменении тех или иных настроек, но тесты не могут помочь воптимизации базы данных. Для оценки производительности запросов необходимо воспользоваться инструкцией EXPLAIN. Эта инструкция, помимо всего прочего, сообщает о том, сколько записей будет прочитано при выполнении заданной инструкции SELECT. Каждая строка результатов соответствует одной исходной таблице, а порядок строк совпадает с порядком обращения к таблицам. Сообщаемое число записей может быть приблизительным, но погрешность очень мала. Произведение счетчиков записей является грубым критерием производительности запроса. Чем меньше это произведение, тем быстрее выполняется запрос.
Представим себе, к примеру, объединение таблицы, содержащей 15000 слов, с таблицей, содержащей 100000 слов. В худшем случае программе MySQL придется просмотреть все записи обеих таблиц. Сначала выбирается первая запись первой таблицы, а затем начинается просмотр записей второй таблицы до тех пор, пока не будет найдено совпадение. Умножив 15000 на 100000, получим 1,5 миллиарда операций чтения. На практике это число оказывается немного меньшим, но и его достаточно, чтобы получить представление о скорости запроса. Далее будет рассказываться о том, как с помощью индексов уменьшить количество записей, читаемых в процессе объединения таблиц.
С помощью журнала медленных запросов, описанного в лекции 8, можно легко найти наименее эффективные запросы. В дистрибутив MySQL входит сценарий mysqldumpslow предназначенный для упорядочения записей этого журнала по указанному в них времени выполнения запроса.
Оптимизация проекта
Давайте вспомним некоторые теоретические аспекты. Нормализация — это такой метод оптимизации базы данных, при котором избыточность хранящейся в ней информации оказывается минимальной. Следовательно, уменьшается время, затрачиваемое приложением на поддержание целостности базы данных. Нормализация достигается за счет повышения объема работы, выполняемой сервером, так как увеличивается число таблиц и серверу приходится чаще создавать их объединения. В процессе денормализации в базу данных вносят некоторую избыточность, чтобы сократить объем работы по извлечению информации.
Наиболее эффективный тип денормализации включает создание итоговых данных. Под этим может подразумеваться добавление к таблице столбца, хранящего результаты вычислений по другим столбцам. Например, если в таблице накапливаются данные о прохождении грузов, то в ней будут столбцы с указанием времени прибытия и отбытия груза. Чтобы не вычислять каждый раз время стоянки, можно посчитать его один раз и занести результат в отдельный столбец. Управлять подобной избыточностью несложно.
Иногда создают не просто итоговые столбцы, а целые таблицы. Например, можно сохранять результаты ключевых запросов в таблице, которая обновляется раз в день. Это избавит сервер от необходимости все время выполнять одни и те же трудоемкие запросы, хотя и повысит риск получения пользователями неактуальных данных. Если таблицы содержат часто изменяемую информацию, лучше делать их резидентными. Такие таблицы хранятся в памяти и уничтожаются при перезагрузке сервера. Приложение должно быть готово к возможному отсутствию таблицы и должно уметь воссоздавать ее в случае необходимости. Хороший пример — Web-приложение, хранящее параметры сеанса в базе данных.
Реляционные базы данных хорошо работают с типизированными значениями фиксированного размера. В MySQL поддерживаются типы переменной длины, например BLOB и TEXT, но управлять ими сложнее. Такого рода информацию лучше хранить в файлах, а в базе данных достаточно запоминать путевые имена этих файлов в столбцах типа CHAR. Если база данных используется в Web-приложениях, помните о том, что у Web-сервера есть кеш-буфер загружаемых файлов изображений и аудиоклипов, поэтому он будет работать с такими файлами быстрее, чем MySQL.
Еще одна причина избегать столбцов подобного типа заключается в появлении записей переменной длины со всеми вытекающими отсюда последствиями. При внесении изменений такая таблица становится дефрагментированной что приводит к замедлению доступа к ней. Для извлечения динамической строки может потребоваться несколько операций чтения, что также не способствует повышению производительности. О форматах хранения табличных данных рассказывалось в лекции 7, "Физическое хранение данных".
Иногда возникает проблема — определить, когда стоит использовать столбцы типа CHAR, а когда VARCHAR. Если в таблице есть столбцы типа BLOB или TEXT, то предпочтение отдается типу VARCHAR, потому что все записи таблицы будут динамическими. То же самое справедливо для случая, когда средняя размерность значений столбца не превышает половины его размерности. Например, столбец типа VARCHAR (80) средняя размерность которого равна 10 символам, определен правильно. Если же средняя размерность превышает 40 символов, нужно поменять тип столбца на CHAR (80) Данное правило направлено на оптимизацию скорости работы с таблицами. Когда более важным фактором является экономия дискового пространства, то в большинстве случаев следует пользоваться типом VARCHAR. Для таблиц MyISAM поддерживается опция DELAY_KEY_WRITE. Она заставляет программу хранить изменения табличных индексов в памяти, пока таблица не будет закрыта. Это сокращает время записи на диск измененных табличных данных, но также повышает риск повреждения таблицы в случае сбоя сервера. Если используется данная опция, то при каждом перезапуске сервера необходимо проверять таблицы на предмет повреждений.
Процедура analyse() представляет собой удобное средство проверки таблицы после вставки данных, так как она определяет диапазон значений каждого столбца в полученном наборе записей. Ее нужно применять в инструкцииSELECT, которая извлекает все записи отдельной таблицы. На основании анализа таблицы процедура analyse()предложит оптимальный тип данных для каждого столбца.
В некоторых случаях процедура analyse() сообщает о том, что вместо типа CHAR должен применяться тип ENUM. Это происходит, когда столбец содержит небольшое число повторяющихся значений. Столбец типа ENUM занимает гораздо меньше места, поскольку в действительности он хранит лишь номера элементов перечисления. Многие типы данных допускают регулирование своей размерности. Например, в столбце типа CHAR может храниться столько уникальных значений, что приводить его к типу ENUM нет никакого смысла, и все равно формальная размерность оказывается избыточной. То же самое касается типа INT, у которого существуют более "короткие" эквиваленты:MEDIUMINT, SMALLINT и TINYINT. Но не забудьте учесть будущее пополнение таблицы. Например, если в таблице 16000 записей, то для первичного ключа вполне подойдет тип SMALLINT. Если же предполагается, что в таблице будет более 65535 записей, следует остановиться на типе INT.
Обратите внимание на столбцы, в которых не могут присутствовать значения NULL. Для экономии места такие столбцы нужно объявлять со спецификатором NOT NULL. Числовые столбцы, в которых не могут храниться отрицательные числа, должны иметь спецификатор UNSIGNED.
Оптимизация приложений
Подключение к базе данных MySQL происходит относительно быстро в сравнении с другими СУБД, но это время можно еще уменьшить за счет кэширования соединений. Требуется лишь прикладная среда, позволяющая хранить идентификаторы соединений в памяти во время работы сервера. Например, модуль РНР непрерывно работает на Web-сервере. Он поддерживает функцию mysql pconnect(), которая создает постоянные соединения. Получив запрос на подключение к серверу, модуль РНР попытается использовать существующее соединение, если это возможно. В протоколах JDBC и ODBC тоже применяется технология кэширования соединений. Она особенно удобна, когда приложение создает большое число соединений за короткий промежуток времени. К примеру, если приложение вставляет данные в таблицу, можно предварительно помещать данные в буфер, с тем чтобы позднее занести их в таблицу в пакетном режиме. В этом случае лучше сразу же заблокировать таблицу, чтобы не пришлось многократно обновлять табличные индексы.
Приложение может дотировать информацию, извлекаемую из базы данных. Это выгодно, если данные меняются нечасто. Когда изменение данных все же происходит, приложение запрашивает принудительную очистку буфера. Предположим, что в Internet магазине имеется каталог продаваемых товаров. Этот каталог пополняется или обновляется раз в неделю, а то и меньше. Когда приложение отправляет клиенту html-страницу с описанием товара, оно вполне может взять информацию из кэша.
Если администратор захочет воспользоваться приложением для обновления цены товара, он должен будет очистить кэш. То же самое применимо и к программным блокам. Если нужно узнать название, цену и категорию товара, введите один запрос и сохраните полученные значения в программных переменных. Основная работа по выборке данных заключается в поиске нужной записи. Не имеет особого значения, 100 или 1000 байтов извлекаются из нее.
Оптимизация запросов
Незаметно для пользователей программа MySQL оптимизирует предложенияWHERE инструкции SELECT. Обычно не нужно заботиться о том, сколько скобок указано в выражении или каков порядок таблиц в объединении. Вместо этого сосредоточьтесь на индексах. Они позволяют ускорить операции выборки данных за счет замедления операций записи. Конечно, индексы занимают дополнительное место на диске, но они незаменимы с точки зрения эффективной организации таблиц.
Когда программа MySQL извлекает данные из таблицы, ей достаточно просмотреть один индексный столбец, чтобы найти нужные записи и не сканировать всю таблицу. Если к объединенной таблице применимы два индекса, программа выбирает из них тот который позволит прочесть меньшее число записей.
Разрешается создавать индекс, охватывающий несколько столбцов. Программа MySQL может работать с частями индекса, но они должны просматриваться строго слева направо. Например, если индекс включает столбцы имени и фамилии, то при обращении к первому столбцу индекс будет использован, а ко второму — нет (при условии, что перед этим не было обращения к первому столбцу). Это правило применимо и к символам индексируемого столбца, содержащего текстовые данные (тип CHAR, VARCHARили BLOB). Когда в предложении WHERE присутствует оператор LIKE, индекс задействуется лишь в том случае, если шаблон сравнения содержит все литеральные символы слева, а метасимволы — справа. Так, шаблон ‘abc %’разрешает использование индекса, а шаблон ‘abc % xyz’ — нет.
В листинге 10.2 приведены инструкции, создающие две таблицы. Таблица word будет содержать 14346 записей, а таблица dictionary — 104237. В первую таблицу слова заносятся пользователями, а вторая таблица содержит список известных программе слов. Пользователи часто вводят несуществующие слова. Запрос, анализируемый влистинге 10.3, предназначен для выяснения количества распознанных слов. Условию отбора соответствуют 911 записей.
mysql> EXPLAIN SELECT word.word, dictionary.word
-> FROM word LEFT JOIN dictionary
-> ON word.word=dictionary.word
-> WHERE word.class = '_VERBO' \G
*************************** 1.row ***************************
table: word
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14346
Extra: where used
table: dictionary
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
Листинг 10.3. (html, txt)
В запросе участвуют три столбца: столбцы word и class таблицы word и столбец word таблицы dictionary. Известно, что тестовому условию отбора соответствуют 911 записей таблицы word, поэтому наша задача состоит в том, чтобы сократить диапазон сканирования первой таблицы до соответствующего уровня. Для этого необходимо создать индекс по столбцу class. Сначала я планировал включить в индекс только упомянутый столбец, но потом подумал о других запросах, которые приходится направлять таким таблицам. Я, например, часто создаю отчет, в который включается все содержимое таблицы, отсортированное сначала по классам, а затем — по словам. Разумнее будет включить в индекс сразу два столбца (листинг 10.4).
ALTER TABLE word
ADD INDEX (class, word)
Листинг 10.4. (html, txt)
Теперь инструкция EXPLAIN выдает другие результаты (листинг 10.5). В поле Key len сообщается о том, что индекс охватывает 16 символов столбца class. По оценке программы MySQL, ей придется просмотреть 1517 записей, хотя мы знаем, что их всего 911
Mysql > EXPLAIN SELECT word. word, dictionary. Word
-> FROM word LEFT JOIN dictionary
-> ON word. Word = dictionary. Word
-> WHERE word. Class = "_VERBO" \G
table: word
type: ref
possible keys: class
key: class
key len: 16
ref: const
rows: 1517
Extra: where used; Using index
table: dictionary
type: ALL
possible keys: NULL
key: NULL
key len: NULL
ref: NULL
rows: 104237
Extra:
2 rows in set (0.00 sec)
Листинг 10.5. (html, txt)
Итак, появление индекса привело к сокращению диапазона сканирования в 15 раз, но инструкция все же вынуждена просматривать 45 миллионов записей. Осталось еще учесть столбцы word в обеих таблицах. Разберемся сначала с таблицей word. В процессе объединения таблиц программа MySQL использует не более одного индекса от каждой таблицы. Если появляются варианты, то выбирается индекс с более узким диапазоном. Созданный нами индекс уже охватывает столбец word, к тому же, как видно из листинга 10.5, диапазон поиска существенно сузился. Теперь перейдем к таблице dictionary. Пока что инструкция SELECT вынуждена сканировать ее целиком. Добавление индекса к столбцу word позволит программе сразу же находить нужную запись (листинг 10.6).
ALTER TABLE dictionary
ADD INDEX (word)
Листинг 10.6. (html, txt)
Эффект этого действия продемонстрирован в листинге 10.7. Как видите, количество просматриваемых записей таблицы dictionary сократилось до одной!
Mysql > EXPLAIN SELECT word. word, dictionary. Word
-> FROM word LEFT JOIN dictionary
-> ON word. Word = dictionary. Word
-> WHERE word. Class = "_VERBO" \G
*********************** 1. row ********************
table: word
type: ref
possible keys: class
key: class
key len: 16
ref: const
rows: 1517
Extra: where used; Using index
table: dictionary
type: ref
possible keys: word
key: word
key len: 64
ref: word. word
rows: 1
Extra: Using index
2 rows in set (0.26 sec)
Листинг 10.7. (html, txt)
Оптимизация инструкций
От оптимизации больше всего выигрывают запросы на выборку, но существуют также методики повышения эффективности других инструкций, в частности INSERT. Можно избежать затрат времени на анализ инструкции, если воспользоваться преимуществами значений по умолчанию. Вместо того чтобы указывать значения всех столбцов, задайте лишь те из них, которые отличаются от стандартных установок, а остальное пусть сделает MySQL. Сказанное иллюстрирует листинг 10.8, в котором показаны определение таблицы и инструкция INSERT
CREATE TABLE address {
ID int (11) NOT NULL AUTO INCREMENT,
Name Prefix CHAR (16) default NULL,
Name First CHAR (32) default NULL,
Name Middle CHAR (32) default NULL,
Name Last CHAR (64) NOT NULL default,
Name Suffix CHAR (16) default NULL,
Company CHAR (64) default NULL,
Street1 CHAR (64) default NULL,
Street2 CHAR (64) default NULL,
Street3 CHAR (64) default NULL,
City CHAR NOT NULL default ‘’,
State Prov CHAR (64) NOT NULL default,
Postal Code CHAR (16) NOT NULL default,
Country Code CHAR (2) default NULL,
Phone1 CHAR (32) default NULL,
Phone2 CHAR (32) default NULL,
Fax CHAR (32) default NULL,
Email CHAR (64) NOT NULL default ‘’,
PRIMARY KEY (ID)
};
INSERT INTO address (Name First, Name Last)
VALUES (‘Leon’, ‘Atkinson’);
Листинг 10.8. (html, txt)
По умолчанию операции записи имеют приоритет над операциями чтения, но программа MySQL не прервет выполнение инструкции SELECT, если в очереди вдруг появится инструкция INSERT. Последняя окажется заблокированной до тех пор, пока инструкция SELECT не завершится. У инструкции INSERT есть также специальный флаг DELAYED, при наличии которого инструкция помещается в очередь без блокирования клиентского приложения, что повышает его оперативность.
Если есть несколько записей, предназначенных для вставки в таблицу, воспользуйтесь многострочной инструкциейINSERT. Еще быстрее работает инструкция LOAD DATA INFILE. Для полной очистки таблицы лучше вызывать инструкцию TRUNCATE TABLE, а не DELETE. В этом случае программа MySQL удалит и снова создаст табличный файл, вместо того чтобы удалять записи одна за другой.
Если в состав инструкции входит сложное выражение, замените его пользовательской функцией. Естественно, это имеет смысл делать только тогда, когда предполагается многократно вызывать инструкцию. О создании собственных функций рассказывается в лекции 13, "Расширение возможностей MySQL".