回答:
MySQLは現在、条件付きインデックスをサポートしていません。
あなたが求めていることを達成するために(あなたはそれをするべきではありません;))補助テーブルの作成を始めることができます:
CREATE TABLE `my_schema`.`auxiliary_table` (
`id` int unsigned NOT NULL,
`name` varchar(250), /* specify the same way as in your main table */
PRIMARY KEY (`id`),
KEY `name` (`name`)
);
次に、メインテーブルに3つのトリガーを追加します。
delimiter //
CREATE TRIGGER example_insert AFTER INSERT ON main_table
FOR EACH ROW
BEGIN
IF NEW.status = 'ACTIVE' THEN
REPLACE auxiliary_table SET
auxiliary_table.id = NEW.id,
auxiliary_table.name = NEW.name;
END IF;
END;//
CREATE TRIGGER example_update AFTER UPDATE ON main_table
FOR EACH ROW
BEGIN
IF NEW.status = 'ACTIVE' THEN
REPLACE auxiliary_table SET
auxiliary_table.id = NEW.id,
auxiliary_table.name = NEW.name;
ELSE
DELETE FROM auxiliary_table WHERE auxiliary_table.id = OLD.id;
END IF;
END;//
CREATE TRIGGER example_delete AFTER DELETE ON main_table
FOR EACH ROW
BEGIN
DELETE FROM auxiliary_table WHERE auxiliary_table.id = OLD.id;
END;//
delimiter ;
トリガー内で
delimiter //
使用したいので必要です;
。
このように、補助テーブルには、トリガーによって更新される文字列「ACTIVE」を含むメインテーブルの行に対応するIDが正確に含まれます。
でそれを使用するにはselect
、通常のものを使用できますjoin
:
SELECT main_table.* FROM auxiliary_table LEFT JOIN main_table
ON auxiliary_table.id = main_table.id
ORDER BY auxiliary_table.name;
メインテーブルに既にデータが含まれている場合、またはデータを異常な方法で変更する外部操作を行う場合(例:MySQLの外部)、これで補助テーブルを修正できます。
INSERT INTO auxiliary_table SET
id = main_table.id,
name = main_table.name,
WHERE main_table.status="ACTIVE";
パフォーマンスについては、おそらく挿入、更新、削除が遅くなります。これは、必要な条件が肯定的であるいくつかのケースを本当に処理する場合にのみ意味をなすことができます。その方法でさえ、おそらく、節約されたスペースが本当にこのアプローチを正当化するかどうかを確認できるのはテストだけです(そして実際にスペースを本当に節約している場合)。
私が質問を正しく理解していれば、あなたがやろうとしていることを達成するのは、NAMEとSTATUSの両方の列にインデックスを作成することだと思います。これにより、NAME = 'SMITH'およびSTATUS = 'ACTIVE'の場所を効率的に照会できます。
これを行うには、2つのテーブル間でデータを分割し、ビューを使用してすべてのデータが必要なときに2つのテーブルを結合し、その列のテーブルの1つだけにインデックスを付けます。ただし、これにより、クエリプランナーが私が信用している以上に賢い場合を除き、テーブル全体を実行します。基本的に、手動でテーブルをパーティション分割します(そしてインデックスをパーティションの1つだけに適用します)。
残念ながら、単一のパーティションにインデックスを適用することはできないため、組み込みのテーブルパーティション機能は、あなたの探求に役立ちません。
インデックスを使用して追加の列を維持し、インデックスの基にする条件がtrueの場合にのみその列に値を持つことができますが、これは労働集約的であり、クエリの効率とスペースの節約。
MySQLには仮想列があり、インデックスに使用できます。
select count(*) from foo where id is null ;
、インデックスを使用できますか?)
decode(status,'ACTIVE',name,null)
たとえば、仮想列をオンにすることができます。