0

実行に約 3 分かかる次の mysql クエリがあります。2 つのサブクエリがありますが、テーブルの行はほとんどありません。説明を行うと、「一時的な使用」が原因のようです。どうやら、以下の「一時的な使用」の指定に示されているように、データベースは 3 つのクエリすべてに対して一時的なテーブルを作成しているようです。

私を混乱させたのは、MySQL のドキュメントによると、temporary の使用は通常、group by と order by が原因であり、どちらも使用していないことです。サブクエリは、暗黙的なグループ化または順序付けを引き起こしますか? グループ化または順序付けに関係なく、一時テーブルを必要とするサブクエリはありますか? MySQL がより効率的に処理できるように、このクエリを再構築する方法に関する推奨事項はありますか? MySQL 設定で他のチューニングのアイデアはありますか?

mysql> explain
SELECT DISTINCT COMPANY_ID, COMPANY_NAME
  FROM COMPANY
 WHERE ID IN (SELECT DISTINCT ID FROM CAMPAIGN WHERE CAMPAIGN_ID IN (SELECT
              DISTINCT CAMPAIGN_ID FROM AD
              WHERE ID=10 AND (AD_STATUS='R' OR AD_STATUS='T'))
              AND (STATUS_CODE='L' OR STATUS_CODE='A' OR STATUS_CODE='C'));

+----+--------------------+----------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type        | table    | type | possible_keys | key  | key_len | ref  | rows | Extra                        |
+----+--------------------+----------+------+---------------+------+---------+------+------+------------------------------+
|  1 | PRIMARY            | COMPANY  | ALL  | NULL          | NULL |    NULL | NULL | 1207 | Using where; Using temporary |
|  2 | DEPENDENT SUBQUERY | CAMPAIGN | ALL  | NULL          | NULL |    NULL | NULL |  880 | Using where; Using temporary |
|  3 | DEPENDENT SUBQUERY | AD       | ALL  | NULL          | NULL |    NULL | NULL |  264 | Using where; Using temporary |
+----+--------------------+----------+------+---------------+------+---------+------+------+------------------------------+

ありがとう!フィル

4

1 に答える 1

3

スキーマの構造はわかりませんが、次のことを試してみます。

CREATE INDEX i_company_id ON company(id);   -- should it be a Primary Key?..
CREATE INDEX i_campaign_id ON campaign(id); -- same, PK here?
CREATE INDEX i_ad_id ON ad(id);             -- the same question applies
ANALYZE TABLE company, campaign, ad;

そして、クエリは次のように単純化できます。

SELECT DISTINCT c.company_id, c.company_name
  FROM company c
  JOIN campaign cg ON c.id = cg.id
  JOIN ad ON cg.campaign_id = ad.campaign_id
 WHERE ad.id = 10
   AND ad.ad_status IN ('R', 'T')
   AND ad.status_code IN ('L', 'A', 'C');

DISTINCTサブクエリの句が大幅に速度を落としている場合は、最後の句で十分です。

于 2012-05-01T05:50:11.920 に答える