2016-04-16 6 views
2

Нижеприведенный запрос занимает несколько минут (никогда не завершается) для выполнения. Я использую базу данных MySQL.SQL-подзапрос, вызывающий общий запрос, чтобы идти медленным

select 
     customer_name as cust, 
     SUM(num_visits) AS visits 
    from 
     visit_history 
    where 
      category = "middleMan" 
      and eve_date >= '2014-07-01' and eve_date <= '2015-07-01 
      and eve_type='XCG' 
      and eve_master IN (select eve_name from master_type_ahj where category = "middleMan" and eve_date >= '2014-07-01' and eve_date <= '2015-07-01') 
    group by 
     cust 
    order by 
     visits desc 
    limit 
     50 

В таблице базы данных содержится более миллиона записей. Данные разделены. Если я должен удалить подзапрос - and eve_master IN (select eve_name from master_type_ahj where category = "middleMan" and eve_date >= '2014-07-01' and eve_date <= '2015-07-01'), запрос завершается через несколько минут.

Индексированные столбцы, которые входят в пункт WHERE.

В любом случае, я мог бы настроить это? Любая помощь здесь поможет мне настроить кучу связанных запросов. Могу я попросить помощь здесь, пожалуйста?

+0

столбцы, поиск по, и рассмотреть возможность использования BETWEEN() для даты сравнений, и/или преобразование Отметки времени Unix. – Alfie

ответ

1

Вот еще один способ с помощью производной таблицы индекса

select 
    customer_name as cust, 
    sum(num_visits) as visits 
from visit_history 
join (
    select distinct eve_name from master_type_ahj 
    where category = "middleMan" 
    and eve_date >= '2014-07-01' 
    and eve_date <= '2015-07-01' 
) t on t.eve_name = visit_history.eve_master 
where category = "middleMan" 
    and eve_date >= '2014-07-01' and eve_date <= '2015-07-01' 
    and eve_type='XCG' 
group by cust 
order by visits desc 
limit 50 
+1

Большое спасибо. Где запрос никогда не возвращался за 30 минут или еще и еще не закончилось, теперь данные за 2 года вернутся примерно через 4 секунды :) Я честно не могу вас поблагодарить. – usert4jju7

+0

@ usert4jju7 рад, что это помогло – FuzzyTree

+0

Также в отношении одного из комментариев выше, используя «BETWEEN» эффективнее (быстрее), чем использовать больше, чем & меньше критериев? Могли бы вы прояснить? – usert4jju7

1

MySQL часто обрабатывает EXISTS лучше, чем IN. Таким образом, это ваш запрос:

select customer_name as cust, SUM(num_visits) AS visits 
from visit_history 
where category = 'middleMan' and 
     eve_date >= '2014-07-01' and eve_date <= '2015-07-01 and 
     eve_type = 'XCG' and 
     exists (select 1 
       from master_type_ahj m2 
       where m2.eve_master = vh.eve_master 
        m2.category = 'middleMan' and 
        m2.eve_date >= '2014-07-01' and eve_date <= '2015-07-01' 
      ) 
group by cust 
order by visits desc 
limit 50; 

Я бы рекомендовал индексы visit_history(category, eve_type, eve_date, eve_master). и master_type_ahj(eve_master, category, eve_date).

+0

Спасибо, Гордон. Я предполагаю, что вы хотели сказать: «MySQL часто обрабатывает EXISTS лучше, чем IN. – usert4jju7

+0

@ usert4jju7. Спасибо. –

+0

Большое спасибо Gordon. Запрос был быстрее, чем в моем вопросе. быстро и, следовательно, я принял ответ. Еще раз спасибо за помощь – usert4jju7

1

Я предложил бы использовать фактическую join будет более эффективным:

select 
     vh.customer_name as cust, 
     SUM(vh.num_visits) AS visits 
    from 
     visit_history as vh 
     inner join 
     master_type_ahj as mt on vh.eve_master = mt.eve_name 
    where 
     vh.category = "middleMan" 
     and vh.eve_date >= '2014-07-01' and vh.eve_date <= '2015-07-01 
     and vh.eve_type='XCG' 
     and mt.category = "middleMan" 
     and mt.eve_date >= '2014-07-01' and mt.eve_date <= '2015-07-01' 

Вы также можете узнать больше с помощью explain, чтобы увидеть, что MySQL фактически делает для обработки вашего запроса.

+0

Спасибо, это еще медленнее. Вышеприведенный ответ с использованием производных таблиц работал как шарм – usert4jju7