Синтаксис оператора INSERT DELAYED
INSERT DELAYED ...
Опция DELAYED для команды INSERT является специфической для MySQL возможностью, которая очень полезна, если клиент не может ждать завершения команды INSERT . Такая проблема встречается часто - она возникает, когда MySQL используется для ведения журналов (проще говоря, для логгинга) и при этом периодически запускаются команды SELECT и UPDATE , для выполнения которых требуется много времени. Оператор DELAYED был введен в версию MySQL 3.22.15. Он является расширением MySQL к ANSI SQL92.
INSERT DELAYED работает только с таблицами типа ISAM и MyISAM . Следует учитывать, что таблицы MyISAM поддерживают одновременное выполнение SELECT и INSERT , поэтому если нет свободных блоков в середине файла данных, то необходимость в применении INSERT DELAYED возникает очень редко. См. раздел Таблицы MyISAM.
При использовании оператора INSERT DELAYED клиент сразу же получает успешный ответ от сервера, а запись будет добавлена в таблицу сразу же после того, как эту таблицу перестанет использовать другой поток.
Еще одно существенное преимущество применения оператора INSERT DELAYED заключается в том, что данные от многих клиентов собираются вместе и записываются одним блоком. Это намного быстрее, чем несколько отдельных операций вставки.
Обратите внимание: в настоящее время все записи, поставленные в очередь на добавление, хранятся только в памяти до тех пор, пока они не будут записаны на диск. Отсюда следует, что если выполнение mysqld будет завершено принудительно (kill -9 ) или программа умрет, то все находящиеся в очереди данные, которые не записаны на диск, будут потеряны!.
Ниже детально описано, что происходит при использовании опции DELAYED в командах INSERT или REPLACE . В этом описании "поток" понимается как поток, принимающий команду INSERT DELAYED , а "обработчик" - это поток, который обрабатывает все команды INSERT DELAYED в конкретной таблице.
При выполнении потоком команды DELAYED для таблицы создается поток-обработчик для обработки всех команд DELAYED в данной таблице, если подобный обработчик уже не существует.
Данный поток проверяет, выполнил ли уже обработчик блокировку DELAYED ; если нет, то он предписывает обработчику сделать это. Блокировка DELAYED может быть осуществлена даже в случае, если блокировки READ или WRITE на данной таблице уже выполнены другими потоками. Однако обработчик будет ожидать всех блокировок ALTER TABLE и завершения всех команд FLUSH TABLES , чтобы убедиться в том, что структура таблицы соответствует последнему обновлению.
Поток выполняет команду INSERT , но вместо записи строки в таблицу он ставит финальную копию этой строки в очередь, управляемую потоком-обработчиком. Поток отмечает все синтаксические ошибки и сообщает о них клиентской программе.
Клиент не может уведомить о количестве дубликатов или значении AUTO_INCREMENT для данной результирующей строки; он также не может получить эти данные с сервера, поскольку команда INSERT возвращает результат до полного завершения операции вставки. По той же причине ничего существенного не даст и использование функции C API mysql_info() .
Обновление журнала обновлений производится потоком-обработчиком после вставки строки в таблицу. В случае многострочной вставки обновление журнала обновлений производится при записи первой строки.
После записи каждых delayed_insert_limit строк, обработчик проверяет, не находятся ли в ожидании выполнения какие-либо команды SELECT . Если да, то обработчик перед продолжением своей работы "пропускает их вперед" на выполнение.
Если очередь обработчика больше не содержит строк, то с данной таблицы будет снята блокировка. Если в течение delayed_insert_timeout секунд не поступят никакие новые команды INSERT DELAYED , то обработчик завершит свою работу.
Если более, чем delayed_queue_size строк уже ожидают в очереди обработчика, то поток, запрашивающий INSERT DELAYED , будет ждать, пока не освободится место в очереди. Таким образом можно иметь уверенность в том, что mysqld не займет всю память сервера для хранения запросов данной очереди.
Поток-обработчик будет наблюдаться в списке процессов MySQL со значением delayed_insert в столбце Command . Поток-обработчик можно уничтожить запуском команды FLUSH TABLES или командой KILL номер_потока . Однако перед своим завершением он вначале сохранит в таблице все поставленные в очередь строки. В процессе сохранения он не будет принимать никаких новых команд INSERT от иного потока. При выполнении после этого команды INSERT DELAYED будет создан новый поток-обработчик. Обратите внимание: отсюда следует, что команды INSERT DELAYED имеют более высокий приоритет, чем обычные команды INSERT , если уже существует запущенный обработчик INSERT DELAYED ! Другие команды обновления должны ожидать, пока не опустеет очередь INSERT DELAYED или же пока кто-либо не прекратит выполнение потока-обработчика (с помощью KILL номер_потока ) или не выполнит FLUSH TABLES .
Представленные в таблице переменные обеспечивают информацию об INSERT DELAYED :
Переменная | Значение | Delayed_insert_threads | Количество потоков-обработчиков | Delayed_writes | Количество строк, записанных INSERT DELAYED | Not_flushed_delayed_rows | Количество строк, ожидающих записи |
Чтобы увидеть эти переменные, следует вызвать команду SHOW STATUS или выполнить команду mysqladmin extended-status .
Обратите внимание: если данная таблица не используется, то команда INSERT DELAYED работает медленнее, чем обычная команда INSERT . Кроме того, возникает дополнительная нагрузка на сервер, поскольку требуется управлять отдельным потоком для каждой таблицы, для которой используется INSERT DELAYED . Это означает, что команду INSERT DELAYED следует применять только тогда, когда в ней есть реальная необходимость!
Синтаксис оператора UPDATE
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name SET col_name1=expr1 [, col_name2=expr2, ...] [WHERE where_definition] [LIMIT #]
Оператор UPDATE обновляет столбцы в соответствии с их новыми значениями в строках существующей таблицы. В выражении SET указывается, какие именно столбцы следует модифицировать и какие величины должны быть в них установлены. В выражении WHERE , если оно присутствует, задается, какие строки подлежат обновлению. В остальных случаях обновляются все строки. Если задано выражение ORDER BY , то строки будут обновляться в указанном в нем порядке.
Если указывается ключевое слово LOW_PRIORITY , то выполнение данной команды UPDATE задерживается до тех пор, пока другие клиенты не завершат чтение этой таблицы.
Если указывается ключевое слово IGNORE , то команда обновления не будет прервана, даже если при обновлении возникнет ошибка дублирования ключей. Строки, из-за которых возникают конфликтные ситуации, обновлены не будут.
Если доступ к столбцу из указанного выражения осуществляется по аргументу tbl_name , то команда UPDATE использует для этого столбца его текущее значение. Например, следующая команда устанавливает столбец age в значение, на единицу большее его текущей величины:
mysql> UPDATE persondata SET age=age+1;
Значения команда UPDATE присваивает слева направо. Например, следующая команда дублирует столбец age , затем инкрементирует его:
mysql> UPDATE persondata SET age=age*2, age=age+1;
Если столбец устанавливается в его текущее значение, то MySQL замечает это и не обновляет его.
Команда UPDATE возвращает количество фактически измененных строк. В версии MySQL 3.22 и более поздних функция C API mysql_info() возвращает количество строк, которые были найдены и обновлены, и количество предупреждений, имевших место при выполнении UPDATE .
В версии MySQL 3.23 можно использовать LIMIT # , чтобы убедиться, что было изменено только заданное количество строк.
1 2 3 4 5 6
8 8 8
| |