Drupalデータベースにインデックスを追加しても安全ですか?


12

私はこれについて検索して読んでいますが、Drupalテーブル(コアとcontribの両方)にインデックスを追加するというトピックについて明確なものを見たことはありません。

私の主な関心事は、コアコードまたはcontribコードを更新し、スキーマが変更されたときにカスタムインデックスで何が起こるかです。この場合はどうなりますか?

編集:

何らかのコンテキストが役立つと思います。主に、サイトのパフォーマンスを調整するためにテーブルにインデックスを追加することに関心があります(クエリがスロークエリログに表示される、ビューが遅いページなど)。これには、他の誰かのモジュールのテーブルにインデックスを追加することが含まれます。例えば

  1. モジュールをインストールします foo
  2. モジュールfooはテーブルを作成します foo
  3. テーブルにインデックスを追加します foo
  4. モジュールにfooは、スキーマを変更する更新があります

何が起こるのですか?

回答:


7

はい、それは問題を引き起こす可能性があります。

モジュールがインデックスを追加した列に対して何かを実行したい場合、モジュールは自身のインデックスを削除してから、意図する操作を実行します。

正確に何が起こるかは、データベースの種類と実際に実行された操作によって異なります。たとえば、列の名前の変更はMySQLでは正常に機能しますが、PostgreSQLでは失敗します。ただし、その列を削除しようとすると(データを別のテーブル/列に移行した後など)、失敗します。

これが起こるだろうという可能性は、比較的低い(ただし、実際のモジュールに依存しない。私は通常追加しないマイナーアップデートのための少なくともいずれかのマイナーリリースに何かを破ることができ、変更を)、それが可能です。

私の提案は、あなたがモジュールメンテナーと協力しようとすることです。問題のあるクエリがモジュール自体からのものである場合、パッチを提供すると、メンテナーはおそらく喜んでインデックスを追加します。インデックスを追加する前後に、問題のあるクエリのDESCRIBE出力を提供します。また、スキーマを更新するパッチを提供します(既存のインストール用に設定する更新機能を含めます)。

パフォーマンス関連のものに積極的に取り組んでおり、上記のことを本当にうまくやっている人はcatchです。ここに例があります:http : //drupal.org/node/983950


2

DatabaseSchema_pgsql :: changeFieldおよびdb_change_field()で報告されているとおり:

重要な注意:データベースの移植性を維持するには、変更されたフィールドを使用しているすべてのインデックスと主キーを明示的に再作成する必要があります。

つまり、db_change_field()を呼び出す前に、db_drop_ {primary_key、unique_key、index}()を使用して、影響を受けるすべてのキーとインデックスを削除する必要があります。キーとインデックスを再作成するには、キー定義をオプションの$ new_keys引数としてdb_change_field()に直接渡します。

たとえば、次のものがあるとします。

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

また、foo.barをシリアルタイプに変更し、それを主キーとして残します。正しいシーケンスは次のとおりです。

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チューナーの使用を検討することもできます。
-tostinni

@tostinniええ、質問はDBチューナーからの推奨事項の実装にほぼ直接関係していました。
mpdonadio
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.