MySql,JOIN和Group By查询是使用临时和文件

时间:2014-01-16 13:10:51

标签: mysql join explain

我有两张表格如下:

  

创建表ox_campaigns
                  campaignid mediumint(9)NOT NULL auto_increment,
                  campaignname varchar(255)NOT NULL默认'',
                  clientid mediumint(9)NOT NULL默认为'0',
                  is_deleted tinyint(1)NOT NULL默认为'0',
                  PRIMARY KEY(campaignid),
                  KEY ox_campaigns_clientidclientid
                )ENGINE = MyISAM DEFAULT CHARSET = utf8

     

创建表ox_clients
                clientid mediumint(9)NOT NULL auto_increment,
                agencyid mediumint(9)NOT NULL默认为'0',
                clientname varchar(255)NOT NULL默认'',
                is_deleted tinyint(4)NOT NULL,
                PRIMARY KEY(clientid),
                独特的钥匙ox_clients_account_idaccount_id),
                KEY ox_clients_agencyidagencyid
              )ENGINE = MyISAM DEFAULT CHARSET = utf8

一个客户可以链接许多广告系列。

我有一个与我竞选的广告系列列表,我想要的是这些广告系列中不同的广告系列列表。

我使用的查询是:

SELECT clients.* 
    FROM 
        clients clients  
    JOIN 
        campaigns campaigns  ON clients.clientid = campaigns.clientid
    WHERE 
        campaigns.is_deleted=0 
        AND campaignid in (2325,2395)
        AND clients.is_deleted=0 
    GROUP BY clients.clientid

它提供的EXPLAIN输出是:

    +----+-------------+-----------+--------+-------------------------------+------+--------------------------------------------------------------------------------------------------------------------
    | id | select_type | table     | type  | possible_keys                 | key    | key_len| ref                      | rows| Extra                                     |
    +----+-------------+-----------+--------+-------------------------------+--------------------------------------------------------------------------------------------------------------------------

    | 1  |    SIMPLE   | campaigns | range | PRIMARY,ox_campaigns_clientid | PRIMARY | 3     |             NULL         | 2 | Using where; Using temporary; Using filesort |

    | 1  |    SIMPLE   | clients   | eq_ref| PRIMARY                       | PRIMARY | 3     | openx.campaigns.clientid | 1 | Using where

为什么它为此查询使用临时和文件排序?

1 个答案:

答案 0 :(得分:2)

由于group by,它正在使用filesort。您可以通过使用exists子句来阻止这种情况:

SELECT clients.* 
FROM clients clients  
WHERE exists (select 1
              from campaigns
              where clients.clientid = campaigns.clientid and
                    campaigns.is_deleted = 0 and
                    campaignid in (2325,2395)
             ) and
      clients.is_deleted = 0 ;

你有一个campaigns_clientid(clientid)的索引,所以这应该使用索引。更好的索引是campaigns_clientid(clientid, is_deleted, campaign_id)。该索引“覆盖”子查询。换句话说,引擎只会使用索引,而不必读入该表的数据页。