[英]MySql , JOIN and Group By query is Using temporary and Filesort
I have 2 tables as below:我有 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
One client can have many campaigns linked to it.一个客户可以关联多个活动。
I have a list of campaignids with me, what I want is a list of distinct clientids for those campaigns.我有一个 campaignids 列表,我想要的是这些活动的不同 clientids 列表。
The query that I am using is:我正在使用的查询是:
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
The EXPLAIN output that it gives is:它给出的 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
Why it is using temporary and filesorting for this query?为什么它为此查询使用临时和文件排序?
It is using filesort because of the group by
.由于group by
,它正在使用文件排序。 You can prevent this by using an exists
clause for what you are doing:您可以通过对您正在做的事情使用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;
You have an index on campaigns_clientid(clientid)
, so this should use the index.您在campaigns_clientid(clientid)
上有一个索引,所以这应该使用索引。 A better index would be campaigns_clientid(clientid, is_deleted, campaign_id)
.更好的索引是campaigns_clientid(clientid, is_deleted, campaign_id)
。 This index "covers" the subquery.该索引“覆盖”了子查询。 In other words, the engine will only use the index and not have to read in the data pages for that table.换句话说,引擎将只使用索引而不必读入该表的数据页。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.