sql >> データベース >  >> RDS >> Mysql

いくつかの大きなベクトルで行をフィルタリングする

    これは、cross joinの概念を使用しています a.k.a.デカルト積(すべての順列)。したがって、配列は、行数がx*y*zの派生テーブル(メモリ内)を生成します。 、ここで、これらのx、y、zは配列のサイズです。サイズ3、4、および5の配列を指定した場合、派生テーブルの行数は3 * 4 * 5=60になります。

    行を生成する提供された配列の一致は、わずか4 * 1 * 1 =4

    でした。

    thing7 以下はあなたが探しているあなたのメインテーブルです。 covering index 大量のデータが含まれていても、これを飛ばす必要があります。カバーリングインデックスとは、提供される情報がインデックスのbツリースキャンを介して提供され、データページの読み取りが不要なインデックスです。なんで?必要なデータがインデックスにあるからです。そしてあなたの場合、非常に薄いです。

    テーブルABCは配列として使用するためのものです。

    他に言うべきことは、すべての派生テーブルには名前が必要だということです。そこで、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. 結果が存在しない場合でもMYSQLは0を表示します

    2. SQLServer浮動小数点データ型の計算と10進数

    3. PostgresまたはCouchDBでの全文検索?

    4. Java SQLData-リスト/配列を使用してユーザーオブジェクトにキャストしますか?