sql >> Databasteknik >  >> RDS >> Mysql

Filtrera rader med flera stora vektorer

Detta använder konceptet med en cross join a.k.a. Cartesian Product (alla permutationer). Så dina arrayer producerar en härledd tabell (i minnet) med radantalet x*y*z , där dessa x,y,z är storlekarna på arrayerna. Om du tillhandahöll arrayer av storlek 3,4 och 5, skulle den härledda tabellen ha ett radantal på 3*4*5=60.

Din angivna arraymatchup som producerar en rad var bara 4*1*1=4

thing7 nedan är din huvudtabell du söker. covering index borde få den här saken att flyga även med massor av data i den. Ett täckande index är ett där den tillhandahållna informationen ges via b-trädsavsökningen av indexet, och som inte behöver läsas av en datasida. Varför? Eftersom den data som behövs finns i indexet. Och i ditt fall extremt tunn.

Tabellerna A B C är avsedda att användas som dina arrayer.

Det enda andra att säga är att varje härledd tabell kräver ett namn. Så vi gav den namnet xDerived i frågan. Tänk på en härledd tabell som något som returneras och används i minnet. Det är inte ett fysiskt bord.

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

Det skulle vara mycket enkelt att göra detta till en sessionsbaserad sökning. Konceptet där är ett där arrayerna som ska sökas (tabeller A B C) har en sessionskolumn. Det skulle då underlätta samtidig användning av flera användare. Men det är att överkonstruera svaret men fråga om du vill ha mer information om det.




  1. MySql välj alla rader i en tabell baserat på MAX-värdet i en annan tabell

  2. Fråga schemadetaljerna för en tabell i PostgreSQL?

  3. Vad är en postgres superanvändare

  4. Lär dig hur man skapar formulär i minnet (Ja, du hörde rätt)