Detta använder konceptet med en cross join
a.k.a. Cartesian Product (alla permutationer). Så dina arrayer producerar en härledd tabell (i minnet) med radantalet x*y*z
, där dessa x,y,z är storlekarna på arrayerna. Om du tillhandahöll arrayer av storlek 3,4 och 5, skulle den härledda tabellen ha ett radantal på 3*4*5=60.
Din angivna arraymatchup som producerar en rad var bara 4*1*1=4
thing7
nedan är din huvudtabell du söker. covering index
borde få den här saken att flyga även med massor av data i den. Ett täckande index är ett där den tillhandahållna informationen ges via b-trädsavsökningen av indexet, och som inte behöver läsas av en datasida. Varför? Eftersom den data som behövs finns i indexet. Och i ditt fall extremt tunn.
Tabellerna A B C är avsedda att användas som dina arrayer.
Det enda andra att säga är att varje härledd tabell kräver ett namn. Så vi gav den namnet xDerived
i frågan. Tänk på en härledd tabell som något som returneras och används i minnet. Det är inte ett fysiskt bord.
Schema
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
);
Test 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 |
+----+---+---+---+
..
Test 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
Det skulle vara mycket enkelt att göra detta till en sessionsbaserad sökning. Konceptet där är ett där arrayerna som ska sökas (tabeller A B C) har en sessionskolumn. Det skulle då underlätta samtidig användning av flera användare. Men det är att överkonstruera svaret men fråga om du vill ha mer information om det.