SELECT
и других запросов
EXPLAIN
(получение информации о SELECT
)SELECT
WHERE
DISTINCT
LEFT JOIN
и RIGHT JOIN
ORDER BY
LIMIT
INSERT
UPDATE
DELETE
Buy this Reference Manual in softcover from Barnes & Noble!
INSERT
Время, необходимое для вставки записи, можно грубо разделить на такие промежутки:
где числа в скобках пропорциональны полному времени. При этом не учитывается время в начале вставки, требующееся для открытия таблиц (таблицы открываются один раз для каждого конкурентно выполняющегося запроса).
Размер таблицы замедляет вставку индексов в log N
раз (B-деревья).
Некоторые способы ускорения вставки:
INSERT
в форме, содержащей множество записей. При этом вставка будет происходить намного быстрее (в некоторых случаях в несколько раз), чем при использовании отдельных операторов INSERT
. При добавлении данных в непустую таблицу можно настроить переменную myisam_bulk_insert_tree_size
так, чтобы это делалось еще быстрее. See section 4.5.6.4 SHOW VARIABLES
.INSERT DELAYED
. See section 6.4.3 Синтаксис оператора INSERT
.MyISAM
можно вставлять строки во время выполнения операторов SELECT
, если в таблицах нет удаленных строк.LOAD DATA INFILE
. При этом обычно вставка будет происходить в 20 раз быстрее, чем при использовании соответствующего количества операторов INSERT
. See section 6.4.9 Синтаксис оператора LOAD DATA INFILE
.LOAD DATA INFILE
выполнялась еще быстрее. Используйте следующую процедуру:
CREATE TABLE
(например, используя mysql
или Perl-DBI
).FLUSH TABLES
или команду оболочки: mysqladmin flush-tables
.myisamchk --keys-used=0 -rq /path/to/db/tbl_name
. После этого индексы не будут использоваться для данной таблицы.LOAD DATA INFILE
. При этом никакие индексы обновляться не будут и, следовательно, скорость будет высокой весьма.myisampack
для этой таблицы, чтобы уменьшить ее размер. See section 4.7.4 myisampack
, MySQL-генератор сжатых таблиц (только для чтения).myisamchk -r -q /path/to/db/tbl_name
. Эта процедура создает индексное дерево в памяти, перед тем как записать его на диск, что гораздо быстрее за счет исключения большого количества дисковых операций. Индексное дерево, получившееся в результате, к тому же отлично сбалансировано.FLUSH TABLES
или команду оболочки: mysqladmin flush-tables
.LOAD DATA INFILE
также выполняет вышеупомянутую оптимизацию при вставках в пустую таблицу. Главное отличие этой команды от вышеупомянутой процедуры заключается в том, что при помощи myisamchk
можно выделить намного больше временной памяти для создания индекса, чем MySQL, по вашему мнению, должен выделять для каждого воссоздания индексов. Начиная с MySQL 4.0 можно также использовать команду ALTER TABLE tbl_name DISABLE KEYS
вместо myisamchk --keys-used=0 -rq /path/to/db/tbl_name
и ALTER TABLE tbl_name ENABLE KEYS
вместо myisamchk -r -q /path/to/db/tbl_name
. Таким образом можно также пропускать шаги FLUSH TABLES
.
mysql> LOCK TABLES a WRITE; mysql> INSERT INTO a VALUES (1,23),(2,34),(4,33); mysql> INSERT INTO a VALUES (8,26),(6,29); mysql> UNLOCK TABLES;Главный фактор, влияющий на скорость, - то, что буфер индексов сбрасывается на диск только один раз, после завершения всех операторов
INSERT
. Обычно содержимое индексных буферов сбрасывалось бы на диск столько раз, сколько имеется различных операторов INSERT
. Блокировка не нужна, если можно вставить все строки при помощи одного оператора. Для транзакционных таблиц, чтобы повысить скорость, следует использовать BEGIN/COMMIT
вместо LOCK TABLES
. Блокировка также понизит полное время проверки подсоединений (multi-connection tests), но максимальное время ожидания для некоторых потоков повысится (потому что они ожидают снятия блокировки). Например:
поток 1 делает 1000 вставок потоки 2, 3 и 4 делают 1 вставку поток 5 делает 1000 вставокЕсли блокировка не используется, 2, 3, и 4 завершат выполнение раньше, чем 1 и 5. Если блокировка используется, 2, 3 и 4, видимо, не закончат выполнение раньше, чем 1 или 5, но общее время должно приблизительно уменьшиться на 40%. Так как в MySQL операции
INSERT
, UPDATE
и DELETE
очень быстрые, общая производительность будет улучшаться, если добавлять блокировки ко всем командам, делающим более 5 вставок или обновлений подряд. Если делается очень много вставок строк, можно время от времени сопровождать команду LOCK TABLES
командой UNLOCK TABLES
(после каждых 1000 строк), чтобы позволить другим потокам обращаться к таблице. Результатом всего этого будет получение хорошей производительности. Конечно, для загрузки данных намного более быстрой является команда LOAD DATA INFILE
.
Чтобы дополнительно повысить скорость выполнения команд LOAD DATA INFILE
и INSERT
, увеличьте буфер ключа (key buffer
). See section 5.5.2 Настройка параметров сервера.
Posted by f f on Wednesday January 29 2003, @9:14pm | [Delete] [Edit] |
You can't imagine how frustrating it is to be told that I can create an insert statement with a "multiple values list" (5.2.9 Speed of INSERT Queries)and not be able to find an example of the syntax on this site (or any other that I know of, for that matter!).
Posted by Jason M on Wednesday February 5 2003, @7:24pm | [Delete] [Edit] |
There is a multi value example above. This one contains 3 rows to be inserterd.
mysql> INSERT INTO a VALUES (1,23),(2,34),(4,33);
Add your own comment.