Безопасно ли добавлять индексы в базу данных Drupal?

12

Я искал и читал об этом, но я не видел ничего определенного в теме добавления индексов в таблицы Drupal (как core, так и contrib).

Моя главная проблема заключается в том, что происходит с любыми пользовательскими индексами, когда вы обновляете основной код или код вклада и происходят изменения схемы. Что происходит в этом случае?

РЕДАКТИРОВАТЬ:

Я думаю, что какой-то контекст может помочь. В первую очередь меня интересует добавление индексов в таблицы для настройки производительности сайта (запросы отображаются в медленном журнале запросов, страницы с медленным просмотром и т. Д.). Это может включать добавление индекса к таблице в чужом модуле. Например

  1. Я устанавливаю модуль foo
  2. Модуль foo создает таблицу foo
  3. Я добавляю индекс в таблицу foo
  4. Модуль fooимеет обновление, которое меняет схему

Что происходит?

mpdonadio
источник

Ответы:

7

Да, это может привести к проблемам.

Если модуль хочет что-то сделать со столбцом, к которому вы добавили индекс, он удалит свои собственные индексы, а затем выполнит все операции, которые он собирается выполнить.

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

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

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

Кто-то, кто активно работает над вещами, относящимися к производительности, и действительно хорошо справляется с вышеперечисленным, - улов, вот пример: http://drupal.org/node/983950

Berdir
источник
2

Как сообщается в DatabaseSchema_pgsql :: changeField и в db_change_field () :

ВАЖНОЕ ПРИМЕЧАНИЕ. Чтобы поддерживать переносимость базы данных, необходимо явно воссоздать все индексы и первичные ключи, которые используют измененное поле.

Это означает, что вы должны удалить все затронутые ключи и индексы с помощью db_drop_ {primary_key, unique_key, index} () перед вызовом db_change_field (). Чтобы воссоздать ключи и индексы, передайте определения ключей как необязательный аргумент $ new_keys непосредственно в db_change_field ().

Например, предположим, у вас есть:

$schema['foo'] = array(
  'fields' => array(
    'bar' => array('type' => 'int', 'not null' => TRUE)
  ),
  'primary key' => array('bar')
);

и вы хотите изменить foo.bar на тип serial, оставив его в качестве первичного ключа. Правильная последовательность:

db_drop_primary_key($ret, 'foo');
db_change_field($ret, 'foo', 'bar', 'bar',
  array('type' => 'serial', 'not null' => TRUE),
  array('primary key' => array('bar'))
);

Аналогичный код сообщается для Drupal 7.

Имейте в виду, что, по моему опыту, вы не можете удалить первичный ключ, который использует последовательное поле. На Drupal 6 я каждый раз получал сообщение об ошибке; Я не пробовал это на Drupal 7.

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

О добавлении индекса в таблицу базы данных, созданную из другого модуля, я бы не советовал делать это, потому что:

  • Модуль не удаляет индекс для изменяемого поля, если сам модуль не создал этот индекс. Модуль не сможет сделать это, потому что он не знает имени индекса.
  • Модификация таблицы базы данных, созданной другим модулем, никогда не будет хорошей идеей, даже если модуль является основным модулем. Если есть другой модуль, который изменяет ту же таблицу, как модули могут обрабатывать любые конфликты, которые они имеют друг с другом, или с изменениями, которые основной модуль будет применять к своей собственной базе данных?

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

Если вы собираетесь добавить индекс к таблице, созданной из другого модуля, на свой собственный сайт, будьте готовы к любым изменениям, которые необходимо вносить в свой пользовательский модуль каждый раз, когда модуль обновляется, и прежде чем устанавливать его на свой собственный сайт. ,
Именно вы можете решить, стоит ли дополнительная работа того, что вы получаете. Лично я не думаю, что оно того стоит.

киамлалуно
источник
Благодарю. Как это будет работать, если я добавлю индекс в таблицу для борьбы с медленным запросом, а не только с изменением моего собственного модуля? Я постараюсь отредактировать свой вопрос, чтобы быть немного более понятным, когда у меня будет шанс.
mpdonadio
3
Также вы можете рассмотреть возможность использования DB Tuner, чтобы узнать, какие индексы создать.
Тостинни
@tostinni Да, вопрос был почти напрямую связан с реализацией рекомендаций DB Tuner.
mpdonadio