Mysql
 sql >> база данни >  >> RDS >> Mysql

Филтриране на редове с няколко големи вектора

Това използва концепцията за 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) имат колона за сесия. Тогава това би улеснило едновременната употреба от много потребители. Но това е прекалено инженерен отговор, но попитайте дали искате повече информация за това.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Внедряване на йерархична структура от данни в база данни

  2. Как мога да съединя A с B и също B с C едновременно?

  3. как да използвам sql join в mysql

  4. mySQL избира пощенски кодове в рамките на x км/мили в обхвата на y

  5. SQL - Актуализирайте множество записи в една заявка