MySQL Slow Writes
Вставка в следующую таблицу занимает до 70 секунд:
CREATE TABLE IF NOT EXISTS `productsCategories` (
`categoriesId` int(11) NOT NULL,
`productsId` int(11) NOT NULL,
PRIMARY KEY (`categoriesId`,`productsId`),
KEY `categoriesId` (`categoriesId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
В таблице около 100 000 строк, и она занимает 7 МБ на диске.
Есть ли в MySQL некоторые настройки, которые могут улучшить производительность записи?
мой my.cnf
Файл выглядит следующим образом:
log-slow-queries="/var/log/mysql/slow-query.log"
long_query_time=1
log-queries-not-using-indexes
innodb_buffer_pool_size=4G
innodb_log_buffer_size=4M
innodb_flush_log_at_trx_commit=2
innodb_thread_concurrency=8
innodb_flush_method=O_DIRECT
query_cache_size = 6G
key_buffer_size = 284M
query_cache_limit = 1024M
thread_cache_size = 128
table_cache = 12800
sort_buffer_size=2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
read_buffer_size=128K
open_files_limit = 1000
table_definition_cache = 1024
table_open_cache = 6000
max_heap_table_size=512M
tmp_table_size=4096M
max_connections=1000
thread_concurrency = 24
Вот аппаратная настройка:
- Dell R710
- RAID10
- 48 ГБ ОЗУ
Учитывая это оборудование, я не ожидал бы, что проблема будет аппаратным узким местом.
2 ответа
НАБЛЮДЕНИЕ № 1
Первое, что бросается в глаза, - это структура стола.
CREATE TABLE IF NOT EXISTS `productsCategories` (
`categoriesId` int(11) NOT NULL,
`productsId` int(11) NOT NULL,
PRIMARY KEY (`categoriesId`,`productsId`),
KEY `categoriesId` (`categoriesId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Пожалуйста, обратите внимание, что categoriesId
index и PRIMARY KEY начинаются с одного столбца. Это избыточный индекс. Поскольку эта таблица InnoDB, categoriesId
index является избыточным по другой причине: все вторичные индексы содержат ключи в gen_clust_index (он же Clustered Index; посмотрите, для чего используется gen_clust_index в mysql?)
Если вы удалите categoriesId
индекс с
ALTER TABLE productsCategories DROP INDEX categoriesId;
это значительно улучшит INSERT из-за отсутствия необходимости выполнять дополнительное обслуживание вторичного и кластерного индекса.
НАБЛЮДЕНИЕ № 2
Если вы выполняете какие-либо операции массовой вставки, вам нужен большой буфер массовой вставки.
Пожалуйста, смотрите мои прошлые сообщения на это:
- https://dba.stackexchange.com/a/16979/877
- /questions/658945/vyi-byi-porekomendovali-windows-vista/658956#658956
- https://dba.stackexchange.com/a/2948/877
НАБЛЮДЕНИЕ № 3
Ваш размер файла журнала слишком мал!!! Это должно быть 25% пула буферов InnoDB, который в вашем случае должен быть 1G. Смотрите мой пост о том, как изменить размер InnoDB Log Files.
НАБЛЮДЕНИЕ № 4
Пожалуйста, не устанавливайте innodb_thread_concurrency!!! Я узнал из первых рук в Percona Live NYC, чтобы оставить это место в покое. По умолчанию он отключен в MySQL 5.5, подключаемом модуле MySQL 5.1 InnoDB и Percona Server 5.1+.
НАБЛЮДЕНИЕ № 5
Вам нужно использовать innodb_file_per_table. Если это отключено, я делаю обслуживание файлов на ibdata1 кошмаром. Пожалуйста, прочитайте мой пост о том, как очистить InnoDB для реализации этого.
НАБЛЮДЕНИЕ № 6
Если вы используете MySQL 5.5 или Percona Server, вам нужно установить определенные параметры, чтобы InnoDB использовал несколько процессоров / несколько ядер. Пожалуйста, смотрите мой пост об этих настройках.
НАБЛЮДЕНИЕ № 7
У тебя есть innodb_log_buffer_size=4M
, По умолчанию это 8M. Это приведет к вдвое большему количеству сброса в журналы повторов. Это также будет противодействовать вашему innodb_flush_log_at_trx_commit=2
установка. Пожалуйста, установите его на 32M. Также, пожалуйста, смотрите документацию MySQL по адресу innodb_log_buffer_size.
В свете этих замечаний добавьте или замените следующие параметры:
[mysqld]
innodb_thread_concurrency = 0
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000
innodb_file_per_table
innodb_log_file_size=1G
innodb_log_buffer_size=1G
bulk_insert_buffer_size = 256M
Вы должны проверить innodb_log_file_size
по умолчанию установлено значение 5M, что довольно мало для интенсивной записи. Попробуйте установить его на 100M. Вам придется удалить старый ib_logfile*
файлы для запуска БД с новыми настройками. Пожалуйста, не удаляйте файлы журналов во время работы сервера БД, вам придется сначала остановить его. Возможно, вам следует сначала сделать резервную копию старых файлов журнала, а не просто удалить их.