2015-03-11 4 views
1

За последние несколько месяцев мы перенесли несколько таблиц из MYiSAM в InnoDB. Мы теоретически делали это для преимущества блокировки строк, поскольку мы обновляем отдельные строки с помощью нескольких экземпляров веб-скрепок. Теперь у меня есть десятки тысяч медленных запросов, созданных в моем slow_query_log (10). и много полного сканирования таблицы. У меня есть событие очень простых обновлений для одной строки (обновление 4 или 5 столбцов) занимает 28 секунд. (наши входы/выходы и эффективность очень хорошие, а неудачные/прерванные попытки очень низкие < 0,5%)Innodb, кластерные индексы и slow_query_log - повреждены первичным ключом?

Две таблицы, которые мы обновляем, имеют в качестве первичного ключа ID (int 11). В InnoDB первичный ключ является кластеризованным ключом, поэтому записываются на диск, индексированный в порядке идентификатора. НО наши две наиболее важные записи, идентифицирующие столбцы, - BillsofLading и Container (оба varchar22). Большинство наших запросов DML ищут записи на основе этих двух столбцов. У нас также есть индексы на BillsofLading и container. Как я понимаю, InnoDB также использует первичный ключ при создании этих двух вторичных индексов.

Таким образом, я мог бы иметь запись с ID = 1, и BillsofLading = 'г', а другая запись ID = 9 и BillsofLading = 'а'. С индексами InnoDB при обновлении записи на основе SELECT, где BillsofLading = 'a', мне еще не нужно было бы выполнять полную проверку, чтобы найти «a», поскольку индекс основан на ID?

Заранее благодарим за помощь здесь!

+0

Первое, что нужно сделать, это запустить EXPLAIN, чтобы узнать, что такое план выполнения запросов и где используются ресурсы. Используйте GI, например Mysql Workbench или Toad, чтобы запустить объяснение, поскольку они представляют результаты намного лучше. –

+0

@DavidSoussan У меня не было никаких очевидных индикаторов из расширенного EXPLAIN. Интересно, является ли это скорее индикатором обработки приложений, а тем более фактическими операторами DML. – user3242558

+0

SHOW CREATE TABLE - могут быть очевидные вещи. –

ответ

1

Нет, ваш пример не должен требовать полного сканирования, предполагая, что MySQL предпочитает использовать ваш индекс BillsofLading. Вы говорите

Как я понимаю, InnoDB также использует первичный ключ при создании этих двух вторичных индексов.

Это правильно, но это не значит, что вы думаете, что это значит.

Первичный ключ (PK) для InnoDB похож на номер строки для человека. Это единственный способ InnoDB однозначно идентифицировать строку. Таким образом, что делает вторичный индекс, сопоставляют каждое значение целевого столбца (ов) со всеми PK (то есть номерами строк), которые соответствуют этому значению. Таким образом, MySQL может быстро перейти только к BillsofLading, о котором вы заботитесь, и затем сканировать только те строки (PK), которые вы хотите.

+0

Ahh, поэтому он находит «BillsofLading» на основе индекса флагов, затем использует первичный ключ (номер строки), чтобы перейти к этой строке для остальных столбцов? Спасибо за объяснение. – user3242558

+1

Несомненно.Чтобы решить ваши общие проблемы с эффективностью запросов, я бы посоветовал начать с худшего нарушителя в медленном журнале запросов (или, возможно, с худшим нарушителем, который также является относительно простым запросом) и выяснить, почему, в частности, этот запрос имеет проблемы. Это может пролить свет на то, почему все остальные запросы также имеют проблемы. – dg99

0

Вы серьезно уменьшили key_buffer_size и установили innodb_buffer_pool_size примерно на 70% доступной оперативной памяти?

Существует несколько тонких различий между MyISAM и InnoDB. В этом ответе слишком много, и ничто из того, что вы сказали, не вызвало особых проблем. Предлагаю вам посмотреть Converting MyISAM to InnoDB, чтобы узнать, что может вызвать проблемы.

+0

Хорошие вопросы. Я изучаю их. Я знаю, что значения ввода/вывода выглядят неплохо. – user3242558