繁体   English   中英

MySql,JOIN 和 Group By 查询正在使用临时和文件排序

[英]MySql , JOIN and Group By query is Using temporary and Filesort

我有 2 个表如下:

CREATE TABLE `ox_campaigns` (                                                       
    `campaignid` mediumint(9) NOT NULL auto_increment,                                
    `campaignname` varchar(255) NOT NULL default '',                                  
    `clientid` mediumint(9) NOT NULL default '0',                                                                                                    
    `is_deleted` tinyint(1) NOT NULL default '0',                                        
    PRIMARY KEY  (`campaignid`),                                                      
    KEY `ox_campaigns_clientid` (`clientid`)                                          
) ENGINE=MyISAM DEFAULT CHARSET=utf8  
CREATE TABLE `ox_clients` (                                   
  `clientid` mediumint(9) NOT NULL auto_increment,            
  `agencyid` mediumint(9) NOT NULL default '0',               
  `clientname` varchar(255) NOT NULL default '',                                                                
  `is_deleted` tinyint(4) NOT NULL,                           
  PRIMARY KEY  (`clientid`),                                  
  UNIQUE KEY `ox_clients_account_id` (`account_id`),          
  KEY `ox_clients_agencyid` (`agencyid`)                      
) ENGINE=MyISAM DEFAULT CHARSET=utf8              

一个客户可以关联多个活动。

我有一个 campaignids 列表,我想要的是这些活动的不同 clientids 列表。

我正在使用的查询是:

SELECT clients.* 
    FROM clients  
    JOIN 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 output 是:

+----+-------------+-----------+-------+-------------------------------+---------+--------+-------------------------------------------------------------------------------+
| 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

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

由于group by ,它正在使用文件排序。 您可以通过对您正在做的事情使用exists子句来防止这种情况发生:

SELECT c.* 
FROM clients c 
WHERE EXISTS (SELECT 1
              FROM campaigns ca
              WHERE ca.clientid = c.clientid AND
                    ca.is_deleted = 0 AND
                    ca.campaignid IN (2325,2395)
             )
      AND c.is_deleted = 0;

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM