使用されている実際のSQLデータベースシステムに関係なく、指定された列のINDEXの存在を確認する統一された方法はありますか?
MySQLの場合、たとえば_SHOW CREATE TABLE mytable
_を使用して存在を確認できます。結果として、列mycolumn
にインデックスKEY 'Index_1' ('mycolumn')
がある場合、次のようになります。
このインジケーターはすべてのSQLデータベースシステムでKEY
統合されていますか?
インデックスを確認するより良い方法はありますか?
そうではないと思います。
ANSI SQL標準では、スキーマ( "INFORMATION_SCHEMA
")は、特定のタイプのオブジェクト(テーブル、ビュー、テーブル列)を検索するために使用できますが、インデックスに関するものは何も含まれていません。
ほとんどのRDBMSには、この情報を公開する独自の内部データディクショナリビューがあります(SQL ServerおよびSybaseではsysindexes
、DBA_INDEXES
Oracleなど)。
MySQLに関しては、 INFORMATION_SCHEMAデータベース を検索する必要があります。
次の表では、すべてのインデックスを介して列を探すことができます。
mysql> show create table information_schema.key_column_usage\G
*************************** 1. row ***************************
Table: KEY_COLUMN_USAGE
Create Table: CREATE TEMPORARY TABLE `KEY_COLUMN_USAGE` (
`CONSTRAINT_CATALOG` varchar(512) NOT NULL DEFAULT '',
`CONSTRAINT_SCHEMA` varchar(64) NOT NULL DEFAULT '',
`CONSTRAINT_NAME` varchar(64) NOT NULL DEFAULT '',
`TABLE_CATALOG` varchar(512) NOT NULL DEFAULT '',
`TABLE_SCHEMA` varchar(64) NOT NULL DEFAULT '',
`TABLE_NAME` varchar(64) NOT NULL DEFAULT '',
`COLUMN_NAME` varchar(64) NOT NULL DEFAULT '',
`ORDINAL_POSITION` bigint(10) NOT NULL DEFAULT '0',
`POSITION_IN_UNIQUE_CONSTRAINT` bigint(10) DEFAULT NULL,
`REFERENCED_TABLE_SCHEMA` varchar(64) DEFAULT NULL,
`REFERENCED_TABLE_NAME` varchar(64) DEFAULT NULL,
`REFERENCED_COLUMN_NAME` varchar(64) DEFAULT NULL
) ENGINE=MEMORY DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> show create table information_schema.statistics\G
*************************** 1. row ***************************
Table: STATISTICS
Create Table: CREATE TEMPORARY TABLE `STATISTICS` (
`TABLE_CATALOG` varchar(512) NOT NULL DEFAULT '',
`TABLE_SCHEMA` varchar(64) NOT NULL DEFAULT '',
`TABLE_NAME` varchar(64) NOT NULL DEFAULT '',
`NON_UNIQUE` bigint(1) NOT NULL DEFAULT '0',
`INDEX_SCHEMA` varchar(64) NOT NULL DEFAULT '',
`INDEX_NAME` varchar(64) NOT NULL DEFAULT '',
`SEQ_IN_INDEX` bigint(2) NOT NULL DEFAULT '0',
`COLUMN_NAME` varchar(64) NOT NULL DEFAULT '',
`COLLATION` varchar(1) DEFAULT NULL,
`CARDINALITY` bigint(21) DEFAULT NULL,
`SUB_PART` bigint(3) DEFAULT NULL,
`PACKED` varchar(10) DEFAULT NULL,
`NULLABLE` varchar(3) NOT NULL DEFAULT '',
`INDEX_TYPE` varchar(16) NOT NULL DEFAULT '',
`COMMENT` varchar(16) DEFAULT NULL,
`INDEX_COMMENT` varchar(1024) NOT NULL DEFAULT ''
) ENGINE=MEMORY DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
たとえば、次のようにColumn_Name_I_Want
列のあるインデックスを検索できます。
SELECT table_schema DB,table_name TBL,
constraint_name NDX,
seq_in_index NDX_POS,position_in_unique_constraint CONST_POS
FROM information_schema.key_column_usage WHERE column_name = 'Column_Name_I_Want'
AND table_schema NOT IN ('information_schema','mysql','performance_schema');
SELECT
table_schema DB,table_name TBL,
index_name NDX,seq_in_index NDXPOS
FROM information_schema.statistics WHERE column_name = 'Column_Name_I_Want'
AND table_schema NOT IN ('information_schema','mysql','performance_schema');
MySQLのINFORMATION_SCHEMAのため、これらのタイプのクエリは遅くなることに注意してください
ベンダー間でのインデックスの実装はありません。インデックスは、ANSI/ISO SQL仕様でも言及されていません。
インデックスはクエリの高速化に役立つ物理的な最適化ですが、インデックスの使用法と動作は実装の詳細として残されます(これは、各RDBMSベンダーがインデックスをサポートする方法を決定し、それらを実行する義務はないという別の言い方です)同じやり方で)。 CREATE INDEX
のようなステートメントが実装間と同様に似ていることは、実際にはかなり驚くべきことです。
したがって、INDEX
やKEY
のような単語の一貫した使用法や、インデックスメタデータをクエリする一貫した方法があるとは期待しないでください。
SQLのany実装全体で同じように実行される100%移植可能なSQLコードを記述できるというのは、かなり神話です。妥協し、テストしてサポートするデータベースのブランドの短いリストに制限する必要があります。
アプリケーションで特定のインデックスを十分に高速に実行する必要がある場合、そのチェックは特定のベンチマーククエリのセットになります。それらが適切に実行される場合は、現在のインデックスで十分です。そうでない場合は、修正が必要です。
アプリケーションが特定のインデックスを正しく実行する必要がある(つまり、一意性または外部キーを確認する)必要があり、これらのインデックスを自分で制御できない場合、最適なソリューションは、そのデータベースの動作を確認するための一連の単体テストです。必要に応じて。
このアプローチは、考えられるすべてのセットアップで機能し、考慮していないシステムにも有用な情報を提供し、主要なデータベースが、同じ方法では検出されない、互換性のない異なる種類のインデックスを提供し始めた場合でも関連性を維持します。
つまり、そのシステムがどのようにしてそれらを達成したかではなく、結果を見てください。