1

この 200 万以上のエントリ テーブル、ID 自動インクリメント、および index1(MainId,SubID,Column1) index2(MainId,SubID,Column2) の場合:

ID  MainID  SubID  Column1    Column2 
--------------------------------------
1     1       A   1A_data_1           
2     1       A              1A_data_2
3     2       B   2B_data_1           
4     2       B              2B_data_2
5     1       A   ignore_me             
6     1       A              1A_data_3

次のインデックスを使用して、目的の列値を含む行 ID を取得できます。

Select max(ID) 
From table where column1 is not null and column1 <>'ignore_me'
Group By MainID,SubID

Select max(id) 
From table where column2 is not null and column2 <>'ignore_me'
Group By MainID,SubID

しかし、私ができないことは、これらを MainID,SubID グループに対して結合してこれらの結果を取得する効率的な方法を見つけることです。

MainID  SubID  Column1    Column2
--------------------------------
  1       A   1A_data_1  1A_data_3
  2       B   2B_data_1  2B_data_2

私は多くの異なるアプローチを試みましたが、永遠にかかるものは何もありません. 別のインデックスが必要ですか? クエリによるグループ化は非常に高速であるため、単純なものを見落としているように感じます。誰かが私を正しい方向に向けることができますか?

4

1 に答える 1

1

条件付き集計を使用して、1 つのクエリで 2 つの ID を計算できます。

SELECT
  MainID,
  SubID,
  MAX(CASE WHEN Column1 <> 'ignore_me' THEN ID END) AS ID1,
  MAX(CASE WHEN Column2 <> 'ignore_me' THEN ID END) AS ID2
FROM atable
GROUP BY
  MainID,
  SubID
;

WHEN 条件に明示的に追加することもできますが、それは必須ではありません。とにかく NULL 値は無視されます。AND ColumnN IS NOT NULL

これで、派生テーブルとして上記のサブクエリを使用して 2 つの左結合を簡単に実行できます。

SELECT
  tm.MainID,
  tm.SubID,
  t1.Column1,
  t2.Column2
FROM (
  SELECT
    MainID,
    SubID,
    MAX(CASE WHEN Column1 <> 'ignore_me' THEN ID END) AS ID1,
    MAX(CASE WHEN Column2 <> 'ignore_me' THEN ID END) AS ID2
  FROM atable
  GROUP BY
    MainID,
    SubID
) tm
  LEFT JOIN atable t1 ON tm.ID1 = t1.ID
  LEFT JOIN atable t2 ON tm.ID2 = t2.ID
;

UPDATE (コメントへの回答としてビューに変換)

これまでのところ、VIEW に適した代替案は 1 つしかありません。

SELECT
  MainID,
  SubID,
  (
    SELECT Column1
    FROM atable
    WHERE MainID = t.MainID
      AND SubID  = t.SubID
      AND Column1 <> 'ignore_me'
    ORDER BY ID DESC
    LIMIT 1
  ) AS ID1,
  (
    SELECT Column2
    FROM atable
    WHERE MainID = t.MainID
      AND SubID  = t.SubID
      AND Column2 <> 'ignore_me'
    ORDER BY ID DESC
    LIMIT 1
  ) AS ID2
FROM atable t
GROUP BY
  MainID,
  SubID
;

ただし、このクエリは前のものよりも遅くなる可能性があります。2 つの相関サブクエリを使用しており、相関サブクエリを使用したクエリ (特にビュー) が MySQL で効率的かどうかはわかりません。適切な索引付けが役立つ場合があります。一般に、これはおそらく自分でテストする必要があります。

于 2013-05-15T19:38:59.850 に答える