Cela utilise le concept d'une cross join
alias produit cartésien (toutes les permutations). Ainsi, vos tableaux produisent une table dérivée (en mémoire) avec un nombre de lignes de x*y*z
, où ces x, y, z sont les tailles des tableaux. Si vous avez fourni des tableaux de taille 3, 4 et 5, la table dérivée aurait un nombre de lignes de 3*4*5=60.
Votre correspondance de tableau fournie qui produit une ligne n'était que de 4*1*1=4
thing7
ci-dessous est votre table principale que vous recherchez. L'covering index
devrait faire voler cette chose même avec une tonne de données dedans. Un index de couverture est un index dans lequel les informations fournies sont données via le balayage b-tree de l'index, et qu'une page de données lue n'est pas nécessaire. Pourquoi? Parce que les données nécessaires sont dans l'index. Et dans votre cas, extrêmement mince.
Les tableaux A B C sont à utiliser comme tableaux.
La seule autre chose à dire est que chaque table dérivée nécessite un nom. Nous lui avons donc donné le nom xDerived
dans la requête. Considérez une table dérivée comme quelque chose renvoyé et utilisé en mémoire. Ce n'est pas une table physique.
Schéma
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
);
Essai 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 |
+----+---+---+---+
..
Essai 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
Il serait très facile de transformer cela en une recherche basée sur la session. Le concept en est un dans lequel les tableaux à rechercher (tables A B C) ont une colonne de session. Cela faciliterait alors l'utilisation simultanée multi-utilisateurs. Mais c'est une ingénierie excessive de la réponse, mais demandez si vous voulez plus d'informations à ce sujet.