2014-01-16 2 views
1

У меня 2 таблицы, как показано ниже:MySql, JOIN и группа По запросу Использования временный и FileSort

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_clientid (clientid)
) ДВИГАТЕЛЬ = MyISAM DEFAULT CHARSET = utf8

CREATE TABLE 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)
UNIQUE KEY ox_clients_account_id (account_id)
KEY ox_clients_agencyid (agencyid)
) ДВИГАТЕЛЬ = 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 

Почему он использует временные и filesorting для этого запроса?

+0

Что такое GROUP BY? – Strawberry

+0

@Strawberry, на самом деле у одного клиента может быть несколько кампаний, связанных с ним, и я хочу только отличную информацию о клиенте для соответствующих идентификаторов кампании. – debaShish

+0

Для этого используйте DISTINCT. При определенных обстоятельствах GROUP BY произведет неожиданные результаты. Хотя MySQL прощает деятельность, GROUP BY не следует использовать при отсутствии каких-либо агрегационных функций. Обратите внимание, что это не проблема производительности. – Strawberry

ответ

2

Используется fileort из-за 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 ; 

У вас есть индекс по campaigns_clientid(clientid), так что это должно использовать индекс. Лучшим индексом будет campaigns_clientid(clientid, is_deleted, campaign_id). Этот индекс «охватывает» подзапрос. Другими словами, движок будет использовать только индекс и не читать на страницах данных для этой таблицы.

+0

спасибо большое @ Gordon, что отлично работает. – debaShish

+1

@debaShish Если вы считаете, что ответ правильный, отметьте его правильно. – Sohaib

Смежные вопросы