2015-01-15 2 views
1

У меня есть две таблицы с несколькими тысячами строк, каждая из которых мне нужна, чтобы присоединиться к дате времени между 2 датами.Производительность, соединяющая строки, где дата находится между датой начала и окончания

select SQL_NO_CACHE * from A 
left outer join R on R.ActivityDate > A.StartDate and R.ActivityDate < A.EndDate; 

В настоящее время запрос довольно медленный. Я попытался добавить индексы, но они не используются в соответствии с результатом объяснения. Какова подходящая стратегия индексирования для такого запроса? Использование между не вместо <>, похоже, не имеет значения.

Если выполняется прямое соединение, запрос выполняется в 13 раз быстрее (на 7% меньше строк), но логически мне нужны непревзойденные строки для возврата. Я бы не ожидал, что разница между двумя типами соединений будет такой большой, если количество дополнительных строк будет настолько низким. Почему внешнее соединение настолько медленнее?

Любая помощь или мысли оценены.

mysql> describe A; 
+-----------+--------------+------+-----+---------+-------+ 
| Field  | Type   | Null | Key | Default | Extra | 
+-----------+--------------+------+-----+---------+-------+ 
| StartDate | datetime  | NO |  | NULL |  | 
| EndDate | datetime  | NO |  | NULL |  | 
| Data  | varchar(100) | NO |  | NULL |  | 
+-----------+--------------+------+-----+---------+-------+ 
3 rows in set (0.00 sec) 

mysql> describe R; 
+--------------+----------+------+-----+---------+-------+ 
| Field  | Type  | Null | Key | Default | Extra | 
+--------------+----------+------+-----+---------+-------+ 
| ActivityDate | datetime | NO |  | NULL |  | 
| Leads  | int(11) | NO |  | NULL |  | 
+--------------+----------+------+-----+---------+-------+ 
2 rows in set (0.00 sec) 
+0

Использование '<' and/or '>' обычно не будет использовать индекс. –

+0

Я не уверен, что вы получите какое-либо улучшение, но попробовали ли вы 'BETWEEN' вместо'> 'и' <'? – Nikos

+0

Я пробовал между. Я добавлю это к вопросу. – Peter

ответ

1

Ведение LEFT JOIN вынудит все строки из появляться независимо от матча

STRAIGHT JOIN или INNER JOIN будет производить только строки, соответствующие положение ON

+0

Логически мне нужны непревзойденные строки, которые нужно вернуть, поскольку мне нужно отображать данные из A, даже если в R. Нет соответствующих строк. – Peter

+0

Почему в таблицах нет поля auto_increment ID? – RolandoMySQLDBA

+0

Я разделил реальные таблицы на вопрос. A имеет идентификатор автоматического увеличения. – Peter

1

Пожалуйста, попробуйте следующее:

select SQL_NO_CACHE 
    * 
from A 
left outer join R 
    on ((R.ActivityDate - A.StartDate) * (R.ActivityDate - A.EndDate))/
     (CASE WHEN ABS((R.ActivityDate - A.StartDate) * (R.ActivityDate - A.EndDate)) = 0 
      THEN 1 
      ELSE ABS((R.ActivityDate - A.StartDate) * (R.ActivityDate - A.EndDate)) 
     END) = -1 

Предложение on, приведенное выше, логически равно тому, которое представлено в вашем вопросе.

Причина в том, что товар (R.ActivityDate - A.StartDate) * (R.ActivityDate - A.EndDate) отрицательный, только если (R.ActivityDate > A.StartDate) and (R.ActivityDate < A.EndDate) состояние выполнено.

Это из-за небольшой трансформации вышеуказанного состояния (R.ActivityDate - A.StartDate) > 0 and (R.ActivityDate - A.EndDate) < 0.

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

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

+0

Это интересно, но производительность примерно такая же, немного медленнее. – Peter

+0

Thx для проверки этого в вашем случае, а также для ответа yor :) С уважением. –

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

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