MySql、JOIN和Group By query正在使用临时和文件排序
我有以下两个表格: 创建表格MySql、JOIN和Group By query正在使用临时和文件排序,mysql,join,explain,Mysql,Join,Explain,我有以下两个表格: 创建表格ox\u活动( activitidmediumint(9)非空自动增量, campaignamevarchar(255)非空默认值“”, clientidmediumint(9)不为空默认值“0”, 已删除tinyint(1)不为空默认值“0”, 主键(活动ID), 按键ox\u活动\u客户端ID(clientid) )ENGINE=MyISAM默认字符集=utf8 创建表ox\u客户端( clientidmediumint(9)非空自动增量, agencyidmed
ox\u活动(
activitid
mediumint(9)非空自动增量,
campaigname
varchar(255)非空默认值“”,
clientid
mediumint(9)不为空默认值“0”,
已删除
tinyint(1)不为空默认值“0”,
主键(活动ID
),
按键ox\u活动\u客户端ID
(clientid
)
)ENGINE=MyISAM默认字符集=utf8
创建表ox\u客户端(
clientid
mediumint(9)非空自动增量,
agencyid
mediumint(9)不为空默认值“0”,
clientname
varchar(255)非空默认值“”,
已删除
tinyint(4)不为空,
主键(clientid
),
唯一键ox\u客户\账户\ id
(账户\ id
),
键ox\u客户端\u代理ID
(agencyid
)
)ENGINE=MyISAM默认字符集=utf8
一个客户端可以有多个活动链接到它
我有一个活动ID列表,我想要的是这些活动的不同客户ID列表
我使用的查询是:
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
它给出的解释输出是:
+----+-------------+-----------+--------+-------------------------------+------+--------------------------------------------------------------------------------------------------------------------
| 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 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 ;
您在活动\u clientid(clientid)
上有一个索引,因此应该使用该索引。更好的索引应该是活动\u clientid(clientid,is\u deleted,campaign\u id)
。此索引“覆盖”子查询。换句话说,引擎将只使用索引,而不必读取该表的数据页。分组依据是什么?@草莓,实际上一个客户端可以链接多个活动,我只需要相应活动ID的不同客户端信息。请使用distinct。在某些情况下,分组将产生意外的结果。尽管MySQL允许此活动,但在没有任何聚合函数的情况下不应使用GROUPBY。请注意,这不是性能问题。@debaShish如果您认为答案正确,请将其标记为正确。