0
account
act_id | act_name | grp_id  | grp_id_2
2      | test     |      4  | 10

promotion
pml_id | act_id   | grp_id 
2      | 2        | null
3      | null     | 4
4      | null     | 10

上に示すように、2 つのテーブルがあります (トリミングされています)。アカウントには約 15000 のレコード、プロモーションには約 20000 のレコードがあります。

顧客は基本的に、「テスト」などのアカウント名を検索できるようにすることを望んでいます。そして、プロモーション 2、3、および 4 が表示されます。

アカウント「test」の grp_id = 4 のため、プロモーション 3 が表示されます。

アカウント「test」は grp_id_2 = 10 であるため、プロモーション 4 が表示されます。

私はもともとこれをいくつかの結合で行いました

SELECT pml_id FROM promotion 
    LEFT JOIN account AS account1 ON promotion.act_id = account1.act_id
    LEFT JOIN account AS account2 ON promotion.grp_id = account2.grp_id
    LEFT JOIN account AS account3 ON promotion.grp_id = account3.grp_id_2
WHERE account1.act_name LIKE 'test%' or account2.act_name LIKE 'test%' 
      or account3.act_name LIKE  'test%'
GROUP BY pml_id

これに関する問題は、アカウント テーブルに 5 回参加しなければならなくなったときに長い時間がかかることです。また、約10000000件のレコードが得られました(group byなしで)。ほとんどのプロモーションは grp_id を使用しますが、act_id を使用することはめったにありません。

このシナリオで act_name 列をすばやく検索する方法はありますか? それほど多くの結合を行う必要はありませんか?

act_id、pml_id、grp_id、grp_id_2 に単一のインデックスがあります。

注: これは、ユーザーがアカウントで検索できないクエリの一部です。IE where句は常にそこにあるとは限りません

4

2 に答える 2

0

これはもっと速いですか?

SELECT pml_id FROM promotion p
  LEFT JOIN account a
  ON (p.act_id = a.act_id OR p.grp_id = a.grp_id OR p.grp_id = a.grp_id_2)
WHERE a.act_name LIKE "test%";

これも試してみてください。act_id にインデックスがある場合は、かなり高速になるはずです。

SELECT * FROM promotion p
LEFT JOIN account a
  ON (p.act_id = a.act_id OR p.grp_id = a.grp_id OR p.grp_id = a.grp_id_2)
WHERE a.act_id IN (
    SELECT act_id FROM account WHERE act_name LIKE "test%"
)
于 2013-09-13T03:20:24.897 に答える