Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Filtern Sie Zeilen mit mehreren großen Vektoren

Dabei wird das Konzept eines cross join verwendet auch bekannt als kartesisches Produkt (alle Permutationen). Ihre Arrays erzeugen also eine abgeleitete Tabelle (im Speicher) mit einer Zeilenanzahl von x*y*z , wobei diese x,y,z die Größen der Arrays sind. Wenn Sie Arrays der Größe 3, 4 und 5 angeben, hätte die abgeleitete Tabelle eine Zeilenanzahl von 3*4*5=60.

Ihr bereitgestellter Array-Matchup, der eine Zeile erzeugt, war nur 4*1*1=4

thing7 unten ist Ihre Haupttabelle, die Sie suchen. Der covering index sollte dieses Ding auch mit einer Tonne Daten darin zum Fliegen bringen. Ein abdeckender Index ist ein Index, bei dem die bereitgestellten Informationen über den B-Tree-Scan des Index bereitgestellt werden und bei dem das Lesen einer Datenseite nicht erforderlich ist. Wieso den? Denn die benötigten Daten befinden sich im Index. Und in Ihrem Fall extrem dünn.

Die Tabellen A B C dienen als Arrays.

Das einzige, was zu sagen ist, ist, dass jede abgeleitete Tabelle einen Namen benötigt. Also gaben wir ihm den Namen xDerived in der Abfrage. Stellen Sie sich eine abgeleitete Tabelle als etwas vor, das zurückgegeben und im Speicher verwendet wird. Es ist keine physische Tabelle.

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

Es wäre sehr einfach, dies in eine sitzungsbasierte Suche umzuwandeln. Das Konzept dort ist eines, bei dem die zu durchsuchenden Arrays (Tabellen A B C) eine Session-Spalte haben. Es würde dann die gleichzeitige Verwendung durch mehrere Benutzer erleichtern. Aber das ist eine Overengineering-Antwort, aber fragen Sie, ob Sie weitere Informationen dazu wünschen.