概要
DROP INDEX 文はテーブル定義からインデックスを削除します。DROP INDEX を使用して、標準のインデックス、ビットマップ・インデックス、またはビットスライス・インデックスを削除できます。また、DROP INDEX を使用すると、対応する Unique インデックスを削除することにより、一意の制約または主キー制約を削除できます。ビットマップ・エクステント・インデックスやマスタ・マップ (データ/マスタ) IDKEY インデックスの削除に DROP INDEX を使用することはできません。
インデックスを削除する理由には、次のようなものがあります。
-
テーブルに対して頻繁に INSERT、UPDATE、DELETE を実行する必要がある場合。このような各操作でインデックスに書き込みが行われ、パフォーマンスのオーバーヘッドが増加する場合は、各操作に %NOINDEX オプションを使用することができます。または、状況によっては、インデックスを削除し、データベースへの変更を一括して行った後、インデックスを再作成および生成する方法もあります。
-
クエリ操作に使用されないフィールド、またはフィールドの組み合わせにインデックスが存在する場合。この場合、インデックスをメンテナンスするパフォーマンスのオーバーヘッドがあまり大きくない場合があります。
-
現在、重複するデータが大量に含まれているフィールドまたはフィールドの組み合わせにインデックスが存在する場合。この場合、クエリのパフォーマンスはあまり改善されない場合があります。
IDKEY インデックスは、テーブルにデータがあるときは削除できません。これを実行しようとすると、SQLCODE -325 エラーが生成されます。
特権とロック
DROP INDEX コマンドは特権を必要とする操作です。DROP INDEX を実行するには、ユーザは %ALTER_TABLE 管理特権を持っている必要があります。持っていない場合、SQLCODE –99 エラーが発生し、%msg が "ユーザ 'name' は %ALTER_TABLE 特権を持っていません" に設定されます。適切な付与特権を持っていれば、GRANT コマンドを使用して、ユーザまたはロールに %ALTER_TABLE 特権を割り当てることができます。管理特権はネームスペース固有のものです。詳細は、"InterSystems SQL の使用法" の "特権" を参照してください。
ユーザは、指定されたテーブルに対する %ALTER 特権を持っている必要があります。ユーザがテーブルの所有者 (作成者) である場合、ユーザにはそのテーブルに対する %ALTER 特権が自動的に付与されます。そうでない場合は、ユーザにテーブルに対する %ALTER 特権を付与する必要があります。持っていない場合、SQLCODE –99 エラーが発生し、%msg が "ユーザ 'name' は 'Schema.TableName' のテーブル定義を変更するために必要な %ALTER 特権を持っていません。" に設定されます。%CHECKPRIV コマンドを呼び出すことにより、現在のユーザが %ALTER 特権を持っているかどうかを確認できます。GRANT コマンドを使用して、指定したテーブルに %ALTER 特権を割り当てることができます。詳細は、"InterSystems SQL の使用法" の "特権" を参照してください。
-
DROP INDEX は、テーブル・クラスの定義に [DdlAllowed] が含まれている場合を除き、永続クラスから投影されたテーブルでは使用できません。使用すると、操作は SQLCODE -300 エラーで失敗し、%msg が “DDL がクラス schema.tablename に対して有効になっていません” に設定されます。
-
DROP INDEX は、導入済みの永続クラスから投影されたテーブルでは使用できません。この操作は SQLCODE -400 エラーで失敗し、%msg が “導入済みのクラス classname を変更する DDL を実行できません” に設定されます。
DROP INDEX 文は、table-name に対してテーブル・レベルのロックを取得します。これにより、他のプロセスはこのテーブルのデータを変更できなくなります。このロックは、DROP INDEX 操作が終了すると自動的に解除されます。
インデックス名
インデックスを作成するために index-name を指定すると、システムは対応するクラス・インデックス名を句読点を削除して生成し、指定した index-name をインデックスの SqlName 値としてクラスに保持します (SQL マップ名)。index-name を DROP INDEX に指定する際、[SQL マップ名] としてテーブルの管理ポータルの SQL の [カタログの詳細] にリストされる、句読点を含む名前を指定します。例えば、[インデックス名] (MYTABLEUNIQUE2) ではなく、Unique 制約の生成された [SQL マップ名] (MYTABLE_UNIQUE2) を指定します。この index-name では、大文字と小文字は区別されません。
テーブル名
インデックスに関連するテーブルは、以下の DROP INDEX 構文形式を使用して指定できます。
どちらの構文でも、テーブル名は未修飾 (table) または修飾 (schema.table) のいずれでもかまいません。スキーマ名を省略すると、既定のスキーマ名が使用されます。
DROP INDEX でテーブル名が指定されていない場合、InterSystems IRIS は index-name と一致するインデックス SqlName のすべてのインデックス、またはインデックスに対して SqlName が指定されていない場合はインデックスの index-name と一致するインデックス名のすべてのインデックスを検索します。InterSystems IRIS がどのクラスでも一致するインデックスを検出しなかった場合、そのようなインデックスが存在しないことを示す SQLCODE -333 エラーが発生します。一致するインデックスを InterSystems IRIS が複数検出した場合、削除するインデックスを DROP INDEX が決定できないため、SQLCODE -334 エラー ("インデックス名が曖昧です。複数のテーブルでインデックスが見つかりました。") が発生します。InterSystems IRIS のインデックス名は、ネームスペースごとに一意ではありません。
存在しないインデックス
既定では、存在しないインデックスを削除しようとすると、DROP INDEX から SQLCODE -333 エラーが発行されます。現在の設定を確認するには、$SYSTEM.SQL.CurrentSettings()Opens in a new tab を呼び出します。これにより、[存在しないインデックスに対してDDLのDROPを許可] 設定が表示されます。既定値は 0 (“いいえ”) です。これが推奨設定です。1 (“はい”) に設定した場合、存在しないインデックスに対する DROP INDEX は処理を実行せず、エラー・メッセージも発行しません。詳細は、"システム管理ガイド" にリストされている SQL およびオブジェクトの設定ページを参照してください。
管理ポータル、[システム管理]、[構成]、[SQL とオブジェクトの設定]、[SQL] から [冗長な DDL ステートメントを無視] チェック・ボックスにチェックを付けることにより、このオプション (および他の同様の作成、変更、および削除のオプション) をシステム全体で設定できます。
述語 IF EXISTS の動作は、管理ポータルでの設定および DDL 文を制御する構成パラメータ・ファイル (CPF) での設定Opens in a new tabよりも優先されます。これらの設定によって SQLCODE 0 が返され、通知なしでエラーが抑制されます。IF EXISTS を指定していると、このコマンドからはメッセージと共に SQLCODE 1 が返されます。
ジャーナリング
%NOJOURN キーワードを指定すると、DROP INDEX によってジャーナリングが抑制され、このオペレーション中はトランザクションが無効になります。%NOJOURN を指定するには、%NOJOURN SQL 管理特権が必要です (GRANT コマンドで設定できます)。
テーブル名
オプションの table-name を指定する場合は、既存のテーブルに対応している必要があります。
-
指定した table-name が存在しない場合、InterSystems IRIS は SQLCODE -30 エラーを発行し、%msg が "テーブルの SQLUser.tname は存在しません" に設定されます。
-
指定した table-name は存在するけれども index-name という名前のインデックスがない場合、InterSystems IRIS は SQLCODE -333 エラーを発行し、%msg が "テーブル SQLUSER.TNAME 上の DROP INDEX MyIndex への試みが失敗しました。インデックスが見つかりません。" に設定されます。
-
指定した table-name がビューの場合、InterSystems IRIS は SQLCODE -333 エラーを発行し、%msg が "ビュー SQLUSER.VNAME 上の DROP INDEX EmpSalaryIndex への試みは失敗しました。" に設定されます。インデックスは、ビューではなく、テーブルに対してのみサポートされています。
例
最初の例では、Employee という名前のテーブルを作成しています。これは、このセクションのすべての例で使用されます。
以下の埋め込み SQL 例は、"EmpSalaryIndex" という名前のインデックスを作成し、後でそれを削除します。この例の DROP INDEX では、インデックスに関連付けられているテーブルが指定されておらず、このネームスペース内で "EmpSalaryIndex" が一意のインデックス名であると想定されています。
&sql(CREATE TABLE Employee (
EMPNUM INT NOT NULL,
NAMELAST CHAR(30) NOT NULL,
NAMEFIRST CHAR(30) NOT NULL,
STARTDATE TIMESTAMP,
SALARY MONEY,
ACCRUEDVACATION INT,
ACCRUEDSICKLEAVE INT,
CONSTRAINT EMPLOYEEPK PRIMARY KEY (EMPNUM))
)
WRITE !,"SQLCODE=",SQLCODE," Created a table"
&sql(CREATE INDEX EmpSalaryIndex
ON TABLE Employee
(Namelast,Salary))
WRITE !,"SQLCODE=",SQLCODE," Created an index"
/* use the index */
NEW SQLCODE,%msg
&sql(DROP INDEX EmpSalaryIndex)
WRITE !,"SQLCODE=",SQLCODE," Deleted an index"
WRITE !,"message",%msg
以下の埋め込み SQL の例では、ON TABLE 節を使用して、削除するインデックスに関連付けられているテーブルを指定しています。
&sql(CREATE INDEX EmpVacaIndex
ON TABLE Employee
(NameLast,AccruedVacation))
WRITE !,"SQLCODE=",SQLCODE," Created an index"
/* use the index */
&sql(DROP INDEX EmpVacaIndex ON TABLE Employee)
WRITE !,"SQLCODE=",SQLCODE," Deleted an index"
以下の埋め込み SQL の例では、修飾付きの名前構文を使用して、削除するインデックスに関連付けられているテーブルを指定しています。
&sql(CREATE INDEX EmpSickIndex
ON TABLE Employee
(NameLast,AccruedSickLeave))
WRITE !,"SQLCODE=",SQLCODE," Created an index"
/* use the index */
&sql(DROP INDEX Employee.EmpSickIndex)
WRITE !,"SQLCODE=",SQLCODE," Deleted an index"
以下のコマンドは、存在しないインデックスを削除しようとしています。そのため、SQLCODE -333 エラーが生成されます。
DROP INDEX PeopleIndex ON TABLE Employee