MySQL: оптимизация UPDATE многих строк в большой таблице - PullRequest
3 голосов
/ 17 января 2011

Таблица организована с использованием модели вложенного набора . Когда я вставляю что-то, мне нужно переместить все со значениями влево / вправо> пункт назначения влево.

UPDATE projects SET rgt = rgt + 2 WHERE rgt >= @superRgt;

Этот запрос может занять несколько секунд, что недопустимо. Мой вопрос как можно оптимизировать этот запрос? можно ли ..

  • Нормализовать / дефрагментировать / переупорядочить физический макет таблицы?
  • Создать лучшие индексы?
  • Просто будь умнее и избегай проблемы?

Мы используем таблицу Innodb, и у нас уже есть индексы слева, справа и слева / справа. В таблице ~ 100 тыс. Строк.

Ответы [ 2 ]

1 голос
/ 17 января 2011

Никаких волшебных пуль, но несколько мыслей ...

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

Хотя индексы могут ускорять запросы, слишком большое количество индексов может замедлять обновления из-за того, что индексы должны отражать обновления в данных. Обратите внимание, что ваш индекс left фактически не имеет значения, поскольку он является ведущим полем в индексе left/right. Сказав, что, поскольку вы, скорее всего, будете, как правило, использовать запросы ранжирования, индексов на left и right вполне достаточно (то есть я могу быть склонен отбросить индекс left/right, если вы не знаете это используется). Грубо говоря, MySQL может использовать более позднюю часть составных индексов, только если все предыдущие столбцы используются в равенстве ссылках.

Независимо от того, чтобы ускорить выполнение вашего запроса, есть ли вероятность того, что ваши левые / правые поля могут принимать отрицательные значения? Если это так, то вы могли бы «переместить» данные на меньшую сторону точки поворота влево или вправо - в зависимости от того, что приведет к обновлению меньшего числа строк.

Обратите внимание, что если вы обновляете слишком много строк, MySQL вообще не будет использовать индекс. Существует эвристический порог процента строк таблицы (часто, как сообщается, ~ 30%), после которого MySQL откажется использовать индекс. То есть в определенный момент лучше выполнить поиск по одному диску и просканировать всю таблицу, а не выполнять поиск по диску> 30% строк в таблице.

Возвращаясь к основам, отклонились ли вы от (плохих) стандартных настроек конфигурации innodb? См. эту статью для некоторых указателей. По крайней мере, убедитесь, что ваш набор данных может поместиться в innodb_buffer_pool_size (если у вас есть ОЗУ), и измените innodb_flush_log_at_trx_commit на 0 или 2, если ваше приложение позволяет это.

0 голосов
/ 02 февраля 2011

При прочих равных создание дублирующейся временной таблицы с использованием ENGINE = MEMORY должно ускорить ваши обновления.

...