sql >> Base de Datos >  >> RDS >> Mysql

Filtrar filas con varios vectores grandes

Esto utiliza el concepto de una cross join también conocido como producto cartesiano (todas las permutaciones). Entonces, sus matrices producen una tabla derivada (en la memoria) con un recuento de filas de x*y*z , donde esos x, y, z son los tamaños de las matrices. Si proporcionó matrices de tamaño 3, 4 y 5, la tabla derivada tendría un recuento de filas de 3*4*5=60.

Su combinación de matriz proporcionada que produce una fila fue solo 4*1*1=4

thing7 a continuación se muestra la tabla principal que está buscando. El covering index debería hacer que esta cosa vuele incluso con una tonelada de datos. Un índice de cobertura es aquel en el que la información proporcionada se proporciona a través del escaneo de árbol b del índice, y que no se requiere una lectura de la página de datos. ¿Por qué? Debido a que los datos necesarios están en el índice. Y en tu caso, extremadamente delgada.

Las tablas A B C son para usar como matrices.

Lo único que hay que decir es que cada tabla derivada requiere un nombre. Así que le dimos el nombre xDerived en la consulta Piense en una tabla derivada como algo devuelto y utilizado en la memoria. No es una 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
);

Prueba 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 |
+----+---+---+---+

..

Prueba 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

Sería muy fácil convertir esto en una búsqueda basada en sesiones. El concepto allí es uno en el que los arreglos a buscar (tablas A B C) tienen una columna de sesión. Entonces facilitaría el uso simultáneo de múltiples usuarios. Pero eso es sobrediseñar la respuesta, pero pregunte si desea obtener más información al respecto.