Това използва концепцията за cross join
още като декартово произведение (всички пермутации). Така че вашите масиви създават производна таблица (в паметта) с брой редове x*y*z
, където тези x,y,z са размерите на масивите. Ако сте предоставили масиви с размер 3,4 и 5, получената таблица ще има брой редове 3*4*5=60.
Предоставеното от вас съвпадение на масив, което създава ред, е само 4*1*1=4
thing7
по-долу е вашата основна таблица, която търсите. covering index
трябва да накара това нещо да лети дори с много данни в него. Покриващ индекс е този, в който предоставената информация се дава чрез сканиране на b-дървото на индекса и не се изисква четене на страница с данни. Защо? Тъй като необходимите данни са в индекса. А във вашия случай изключително тънък.
Таблици A B C са за използване като ваши масиви.
Единственото друго нещо, което трябва да се каже е, че всяка производна таблица изисква име. Затова му дадохме името 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) имат колона за сесия. Тогава това би улеснило едновременната употреба от много потребители. Но това е прекалено инженерен отговор, но попитайте дали искате повече информация за това.