2017-02-14 2 views
0

все. Вот проблема в моем сервере mysql.
У меня есть таблица около 40 000 000 строк и 10 столбцов.
Его размер составляет около 4 ГБ. И двигатель является innodb.
Это основная база данных, и только один такой sql-код.split table performance in mysql

insert into mytable ... on duplicate key update ... 

А около 99% Прикладных выполнена update часть.

Теперь сервер становится все медленнее и медленнее. Я слышал, что таблица split может повысить ее производительность. Затем я попробовал на своем персональном компьютере, разбил на 10 таблиц, не смог, также попробовал 100, тоже не удалось. Скорость стала медленнее. Поэтому мне интересно, почему разделение таблиц не улучшило производительность?

Заранее спасибо.

более

детали:

CREATE TABLE my_table (
    id BIGINT AUTO_INCREMENT, 
    user_id BIGINT, 
    identifier VARCHAR(64), 
    account_id VARCHAR(64), 
    top_speed INT UNSIGNED NOT NULL, 
    total_chars INT UNSIGNED NOT NULL, 
    total_time INT UNSIGNED NOT NULL, 
    keystrokes INT UNSIGNED NOT NULL, 
    avg_speed INT UNSIGNED NOT NULL, 
    country_code VARCHAR(16), 
    update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY(id), UNIQUE KEY(user_id) 
); 

PS:
Я также пробовал разные компьютеры с твердотельным накопителем и жестким диском, но не помогло тоже.

ответ

0

Попытайтесь разбить вашу базу данных на некоторые экземпляры mysql с использованием прокси-сервера mysql, как mysql-proxy или haproxy, а не на один экземпляр mysql. Возможно, у вас отличная производительность.

+0

Но у моей компании нет большого бюджета для большего количества случаев. Есть ли способ, которым я могу попробовать? Большое спасибо –

+0

, вы можете попытаться сделать резервную копию некоторых данных и удалить их, если вы разрешаете бизнес –

+0

, или вы можете разделить таблицу на 7 или более таблицу. Прочитайте один стол в один день и создайте резервную копию и очистите другие таблицы. –

0

Разделение стола вряд ли поможет вообще. То же самое для PARTITIONing.

Давайте посчитаем образы дисков. Я пропущу подсчет нелистных узлов в BTrees; они, как правило, кэшируются; Я буду считать листовые узлы в данных и индексах; они, как правило, не кэшируются.

IODKU делает:

  1. Read индексный блок, содержащий для любых UNIQUE ключей. В вашем случае это, вероятно, user_id. Просьба представить пример SQL-запроса. 1 читать.
  2. Если запись user_id находится в индексе, прочитайте запись из данных, проиндексированную PK (id), и выполните UPDATE, и оставьте этот второй блок в buffer_pool для возможной перезаписи на диск. 1 читайте сейчас, 1 напишите позже.
  3. Если запись не найдена, сделайте INSERT. Блок индекса, который нуждается в новой строке, уже был прочитан, поэтому он готов к вводу новой записи. Между тем, «последний» блок в таблице (из-за id, являющийся AUTO_INCREMENT), вероятно, уже кэширован. Добавьте к нему новую строку. 0 читается сейчас, 1 напишите позже (UNIQUE). (Переписывание «последнего» блока амортизируется, скажем, 100 строк, поэтому я игнорирую его.)
  4. В конце концов напишите (-ы).

Всего, предполагая, что все они принимают путь UPDATE: 2 чтения и 1 запись. Предполагая, что user_id не соответствует простому шаблону, я предполагаю, что все 3 ввода-вывода являются «случайными».

Давайте рассмотрим вариант ... Что делать, если вы избавились от id? Вам нужно id где-нибудь еще?Поскольку у вас есть ключ UNIQUE, это может быть ПК. Это заменяет ваши два индекса только PRIMARY KEY(user_id). Теперь отсчеты:

  1. 1 прочитал
  2. Если UPDATE, 0 чтение, 1 запись
  3. Если INSERT, 0 читать, 0 написать

Итого: 1 чтение, 1 запись. 2/3, как и раньше. Лучше, но все равно не здорово.

Кэширование

Сколько оперативной памяти у вас есть?
Какая ценность innodb_buffer_pool_size?
SHOW TABLE STATUS - Что такое Data_length и Index_length?

Я подозреваю, что buffer_pool не достаточно большой, и возможный может быть поднят. Если у вас более 4 ГБ ОЗУ, сделайте около 70% ОЗУ.

Другие

SSD-накопители должны значительно помогли, так как вы, кажется, я/вывода. Можете ли вы сказать, связаны ли вы с привязкой к вводу/выводу или с привязкой к процессору?

Сколько строк вы обновляете сразу? Сколько времени это занимает? Разбивается ли он или один за раз? Здесь может быть значительное улучшение.

Вам действительно нужен BIGINT (8 bytes)? INT UNSIGNED - всего 4 байта.

Сделка связана с транзакцией?

Есть ли у мастера проблемы? Раб? И то и другое? Я не хочу исправлять Учителя таким образом, чтобы он испортил Раба.

+0

Спасибо вам большое. Я не думал, чтобы удалить ключ автоматического увеличения. Это фантастика. 1. Я попытался изменить значение innodb_buffer_pool_size, но не помогло. 2. Я также попробовал ваше предложение, чтобы сделать данные собранными, это здорово. 3. BIGINT не может быть изменен из-за данных. 4. И никаких транзакций не было. 5. У мастера есть проблема. –

+0

Полный sql выглядит следующим образом. 'INSERT DELAYED IN mytable (user_id, идентификатор, account_id, top_speed, total_chars, total_time, нажатия клавиш, avg_speed, country_code) VALUES (% s,% s,% s,% s,% s,% s,% s,% s, % s) ON DUPLICATE KEY UPDATE account_id =% s, top_speed =% s, total_chars =% s, total_time =% s, keystrokes =% s, avg_speed =% s "' –

+0

Если репликация «основана на строке», некоторые из них удары диска происходят только в Мастере, а Slave не требует повторного выбора между вставкой и обновлением. Это _may_ объясняет, почему только у Мастера возникают проблемы. –