Isso usa o conceito de uma
cross join
aka Produto cartesiano (todas as permutações). Portanto, seus arrays produzem uma tabela derivada (na memória) com uma contagem de linhas de x*y*z
, onde esses x,y,z são os tamanhos das matrizes. Se você forneceu matrizes de tamanho 3,4 e 5, a tabela derivada teria uma contagem de linhas de 3*4*5=60. Sua correspondência de matriz fornecida que produz uma linha era apenas 4*1*1=4
thing7
abaixo está a tabela principal que você está procurando. O covering index
deve fazer essa coisa voar mesmo com uma tonelada de dados nela. Um índice de cobertura é aquele em que as informações fornecidas são fornecidas por meio da varredura de b-tree do índice e que uma leitura de página de dados não é necessária. Por quê? Porque os dados necessários estão no índice. E no seu caso, extremamente fino. As tabelas A B C são para uso como seus arrays.
A única outra coisa a dizer é que toda tabela derivada requer um nome. Então demos o nome
xDerived
na consulta. Pense em uma tabela derivada como algo retornado e usado na memória. Não é uma mesa física. Esquema
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
);
Teste 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 |
+----+---+---+---+
..
Teste 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
Seria muito fácil transformar isso em uma pesquisa baseada em sessão. O conceito que existe é aquele em que os arrays a serem pesquisados (tabelas A B C) possuem uma coluna de sessão. Isso facilitaria o uso simultâneo de vários usuários. Mas isso é excesso de engenharia da resposta, mas pergunte se você deseja mais informações sobre isso.