2015-04-28 2 views
2

Я пытаюсь получить статистику пользователя из mysql. Что-то вроде:Как оптимизировать несколько подзапросов?

  • 10% пользователей купили Пепси
  • 20% являются женщины
  • 40% из них на США

Первый шаг получить список всех пользователей купили что-то от пепси производитель.

Этот запрос работает менее чем за 1 секунду и возвращает список идентификаторов пользователей.

SELECT DISTINCT idUser FROM checkout_item INNER JOIN (
    SELECT id FROM product WHERE manufacturer = "pepsi" 
) AS chkItem ON chkItem.id = checkout_item.idProduct 

Теперь я пользуюсь этим списком, чтобы получить информацию. Просто добавьте свой запрос выше:

SELECT 
    name, gender 
FROM users INNER JOIN(

    SELECT DISTINCT idUser FROM checkout_item INNER JOIN ( // 
    SELECT id FROM product WHERE manufacturer = "pepsi" // same query above 
) AS chkItem ON chkItem.id = checkout_item.idProduct  // 

) AS usr ON usr.idUser = users.id 

Этот запрос работает, но требуется 23 секунды. Есть ли способ оптимизировать это?

Возможно использование WHERE, JOINs или изменение конфигураций RAM mysql?

+2

Включены ли ваши таблицы? – vaso123

+0

спасибо @lolka_bolka, я создал индексы в полях NAME и GENDER, и теперь это занимает 2 секунды. – anderlaini

+1

Мне трудно поверить, что индексы по имени и полу помогут, поскольку они не включены ни в один из параметров фильтрации. Является ли запрос, который отличается от запроса, который вы опубликовали? –

ответ

1

Перепишите свой первый запрос. Может быть, вы сможете выяснить остальное.

SELECT DISTINCT idUser 
      FROM checkout_item i 
      JOIN product p 
      ON p.id = i.idproduct 
      WHERE p.manufacturer = 'pepsi' 
0

Попробуйте это: Выберите имя, пол из checkout_item с INNER JOIN (Select Id из продукта WHERE производитель = "пепси") р = О p.id C.idProduct INNER JOIN пользователей Мириэль C. idUser = u.Id

Также думаю положить индекс на checkout_item поле idProduct

0

ниже должно дать вам общее количество idUsers, и общее число idUsers, которые женщины (очевидно, я не знаю, что вы используете в качестве флага для пола, поэтому я только что использовал «f»).

SELECT COUNT(DISTINCT idUser) AS Total, 
    COUNT(DISTINCT CASE WHEN gender = 'f' then idUser else null end) AS women 
FROM checkout_item ci 
    inner join product p 
     on p.id=ci.idProduct 
WHERE p.manufacturer = 'pepsi' 

Оттуда должны быть базовые математические данные, чтобы получить нужные цифры.

Обычно я бы не рекомендовал использовать «DISTINCT», однако, не зная о ваших данных, это быстрый и грязный способ сделать что-то, что работает.

Надеюсь, что это поможет!

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