これは、cross join
の概念を使用しています a.k.a.デカルト積(すべての順列)。したがって、配列は、行数がx*y*z
の派生テーブル(メモリ内)を生成します。 、ここで、これらのx、y、zは配列のサイズです。サイズ3、4、および5の配列を指定した場合、派生テーブルの行数は3 * 4 * 5=60になります。
行を生成する提供された配列の一致は、わずか4 * 1 * 1 =4
でした。
thing7
以下はあなたが探しているあなたのメインテーブルです。 covering index
大量のデータが含まれていても、これを飛ばす必要があります。カバーリングインデックスとは、提供される情報がインデックスのbツリースキャンを介して提供され、データページの読み取りが不要なインデックスです。なんで?必要なデータがインデックスにあるからです。そしてあなたの場合、非常に薄いです。
テーブルABCは配列として使用するためのものです。
他に言うべきことは、すべての派生テーブルには名前が必要だということです。そこで、xDerived
という名前を付けました。 クエリで。派生テーブルは、メモリで返され、使用されるものと考えてください。物理的なテーブルではありません。
スキーマ
create table thing7
( id int auto_increment primary key,
A int not null,
B int not null,
C int not null,
index(A,B,C) -- covering index (uber-thin, uber-fast)
);
insert thing7(A,B,C) values
(1,2,7),
(1,2,8),
(2,2,1),
(1,3,1);
create table A
( id int auto_increment primary key,
value int
);
create table B
( id int auto_increment primary key,
value int
);
create table C
( id int auto_increment primary key,
value int
);
テスト1
truncate table A;
truncate table B;
truncate table C;
insert A (value) values (1),(2),(3),(4);
insert B (value) values (2);
insert C (value) values (7);
select t7.*
from thing7 t7
join
( select A.value as Avalue, B.value as Bvalue, C.value as Cvalue
from A
cross join B
cross join C
order by a.value,b.value,c.value
) xDerived
on xDerived.Avalue=t7.A and xDerived.Bvalue=t7.B and xDerived.Cvalue=t7.C;
+----+---+---+---+
| id | A | B | C |
+----+---+---+---+
| 1 | 1 | 2 | 7 |
+----+---+---+---+
..
テスト2
truncate table A;
truncate table B;
truncate table C;
insert A (value) values (1);
insert B (value) values (2);
insert C (value) values (0);
select t7.*
from thing7 t7
join
( select A.value as Avalue, B.value as Bvalue, C.value as Cvalue
from A
cross join B
cross join C
order by a.value,b.value,c.value
) xDerived
on xDerived.Avalue=t7.A and xDerived.Bvalue=t7.B and xDerived.Cvalue=t7.C;
-- no rows returned
これをセッションベースの検索に変えるのは非常に簡単です。検索する配列(テーブルA B C)にセッション列があるという概念があります。これにより、マルチユーザーの同時使用が容易になります。しかし、それは答えを過剰に設計しているのですが、それについてもっと情報が必要かどうか尋ねてください。