Mysqlマルチペアマルチクエリー、カラムマージ


詳細
テーブル情報
  • リソーステーブルsynsource 199824 rows
  • 製品表tab_product_detail                                  108              rows
  • リソースと製品の多対多の関連テーブルtab_r_sourmach  1,113,866   rows

  • 以上の表はいずれもMyISAMエンジンを採用する.
    接続テスト
    ユーザーがより良いリソースの検索を容易にするため、リソースデータをすべてLuceneにインデックス化する必要があります.Luceneに格納したいDocumentは次のとおりです.
    sourceName
    fileName
    subject
    grade
    products
    英語の学生用本第11冊
    外研新标准nwe
    英語
    小学校
    NP7000 NP6000 NP2300
    英語の学生用本第12冊
    外研新基準2.nwe
    英語
    小学校
    NP2300
    上記の4つのフィールドはsynsourceテーブルに属し、productsはtab_に属します.product_detailテーブル、それらの関係はtab_r_sourmachは中間関連付けを行う.
    最初に思いついたのは、以下のSQLをそのまま使うことです.
    
    select s1.sourid, s1.sourcename , t.product_name from synsource s1 
      left join tab_r_sourmach c 
        on s1.sourid=c.sourid
          left join tab_product_detail t 
            on c.product_id = t.product_id where s1.sourceid=1
    

    5 rows in set (0.45 sec)
    sourid
    sourcename       
    subjectname
    product_name
          1
    小六上Module 07
    英語
    ND520       
          1
    小六上Module 07
    英語
    NP560T      
          1
    小六上Module 07
    英語
    NP560+      
          1
    小六上Module 07
    英語
    NP360+      
    以上のSQLの結果重複データの集計処理については
    GROUP_CONCAT:
    select s1.*, GROUP_CONCAT(t.product_name SEPARATOR ' ') as product_name
      from tab_synsource s1 
        left join tab_r_sourmach c
          on s1.sourid=c.sourid
            left join tab_product_detail t 
                  on c.product_id = t.product_id where s1.sourceid=1

    1 row in set (0.31 sec)
    sourid
    sourcename       
    subjectname
    product_name 
    1
    小六上Module 07
    英語
    ND520 NTV518 NP560T NP560+ NP360+
    需要を満たすように見えますが、以上は単一のデータに対してクエリーを行うだけで、データの一括インデックスが確立されると直接limit 500などの操作に違いありません.以上のwhereを削除してlimit 10を加えて実行した後、半日も実行できず、すべてのデータ接続クエリーを行ってからlimitに行くと推定されます.
    そこで、直接(tab_r_sourmach,tab_product_detail)の2つのテーブルの関連付けをテストして、効率を見てみましょう.
    select c.sourid
    from tab_r_sourmach c left join tab_product_detail t 
    on  c.product_id = t.product_id  
    group  by c.sourid limit 500;

    以上の文の使用時:(5.65 sec)
    プラスGROUP_CONCAT試し:
    select c.sourid, GROUP_CONCAT(t.product_name SEPARATOR ' ') as products
    from tab_r_sourmach c left join tab_product_detail t 
    on  c.product_id = t.product_id  
    group  by c.sourid limit 800;

    出力結果サンプル:
    sourid
    products
        767
    ND520 ND416 NTV518 NP560T NP560+ NP360+
        760
    ND550 NP600+ NP9588 NP600
    800 rows in set(1.74 sec)は、繰り返しテストした結果、GROUP_が追加されていることがわかりました.CONCAT関数はこの関数を使っていないより5倍も速く、まだなぜか分かりません.
    しかし、1秒程度はバックグラウンドインデックスの作成には納得できるので、以上のSQLとsynsourceを接続テストします.
    
    select * from synsource s, (
      select c.sourid,
          GROUP_CONCAT(t.product_name SEPARATOR ' ') 
          from tab_r_sourmach c left join tab_product_detail t 
          on 
          c.product_id = t.product_id 
          group  by c.sourid  limit 1000
        ) as b
    where s.sourid = b.sourid;

    出力結果サンプル:
        968
    語彙学習-第3級K(ケンブリッジ少年英語参照)
    英語
    NP600+ NP600
        983
    語彙学習-6年生でUnit 7(湘教版参照)
    英語
    ND520 ND416 NTV518 NP560T NP560+ NP360+
    1000 rows in set (2.02 sec)
    皆さんはこのような状況をどのように処理しているのか分かりません.以上のSQLは目的を達成できますが、まだ不足しています.
    MYSQL GROUP_を使っていますCONCAT関数をグループ化接続する場合、文字列の長さ接続には長さ制限がありますが、デフォルトではproductsが長すぎると切断されますので、一労永逸したいならそのままmy.cnfにgroup_を加えるconcat_max_len=99999でいいです.