2014-01-16 76 views
1

我有2個表如下:MySQL中,JOIN和GROUP BY查詢使用臨時和文件排序

CREATE TABLE 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的默認字符集= UTF8

CREATE TABLE ox_clients
clientid MEDIUMINT(9)NOT NULL的auto_increment,
agencyid MEDIUMINT(9)NOT NULL默認' 0',
clientname varchar(255)NOT NULL default'',
is_deleted tinyint(4)NOT NULL,
PRIMARY KEY(clientid),
UNIQUE KEY ox_clients_account_idaccount_id),
KEY ox_clients_agencyidagencyid
)ENGINE = MyISAM的默認字符集= UTF8

一個客戶可以有很多活動鏈接到它。

我有一個與我的campaignid列表,我想要的是這些活動的不同clientids列表。

,我使用的查詢是:

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

爲什麼它是使用臨時和filesorting此查詢:

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 

,它給的解釋輸出?

+0

什麼是GROUP BY? – Strawberry

+0

@Strawberry,實際上一個客戶可以有多個活動鏈接到它,並且我只需要相應的活動ID的不同客戶端信息 – debaShish

+0

對此使用DISTINCT。在某些情況下,GROUP BY會產生意想不到的結果。雖然MySQL原諒了這個活動,但是GROUP BY不應該用於沒有任何聚合函數的情況。請注意,這不是性能問題。 – Strawberry

回答

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)。該索引「覆蓋」子查詢。換句話說,引擎將只使用索引,而不必讀取該表的數據頁面。

+0

非常感謝@Gordon,完美的作品。 – debaShish

+1

@debaShish如果您認爲答案是正確的,請將其標記爲正確。 – Sohaib