Dit gebruikt het concept van een cross join
aka cartesiaans product (alle permutaties). Dus je arrays produceren een afgeleide tabel (in het geheugen) met een rijtelling van x*y*z
, waarbij die x,y,z de grootte van de arrays zijn. Als u arrays van de grootte 3,4 en 5 opgeeft, zou de afgeleide tabel een rijtelling hebben van 3*4*5=60.
Uw geleverde array-matchup die een rij produceert, was slechts 4*1*1=4
thing7
hieronder is uw hoofdtabel die u zoekt. De covering index
zou dit ding moeten laten vliegen, zelfs met een hoop gegevens erin. Een dekkende index is er een waarin de verstrekte informatie wordt gegeven via de b-tree-scan van de index en waarbij het lezen van een gegevenspagina niet vereist is. Waarom? Omdat de benodigde gegevens in de index staan. En in jouw geval extreem dun.
Tabellen A B C zijn voor gebruik als uw arrays.
Het enige andere om te zeggen is dat elke afgeleide tabel een naam vereist. Dus gaven we het de naam xDerived
in de vraag. Beschouw een afgeleide tabel als iets dat wordt geretourneerd en in het geheugen wordt gebruikt. Het is geen fysieke tafel.
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
Het zou heel gemakkelijk zijn om dit om te zetten in een sessiegebaseerde zoekopdracht. Het concept daar is er een waarin de te doorzoeken arrays (tabellen A B C) een sessiekolom hebben. Het zou dan gelijktijdig gebruik door meerdere gebruikers mogelijk maken. Maar dat is over-engineering van het antwoord, maar vraag of je daar meer informatie over wilt.