В SQL влияет ли порядок предложений WHERE? - PullRequest
4 голосов
/ 12 мая 2011

У меня есть таблица в моей БД примерно так:

 ----------------------------------------------------------
| event_id | date       | start_time | end_time | duration |
 ----------------------------------------------------------
| 1        | 2011-05-13 | 01:00:00   | 04:00:00 | 10800    |
| 2        | 2011-05-12 | 17:00:00   | 01:00:00 | 28800    |
| 3        | 2011-05-11 | 11:00:00   | 14:00:00 | 10800    |
 ----------------------------------------------------------

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

<code>SELECT *
FROM event_schedules
WHERE (
       date = CURDATE() //today
       OR
       date = DATE_SUB(CURDATE(), INTERVAL 1 DAY) //yesterday
      )
  // and ended before now()
  AND DATE_ADD(CONCAT(date, ' ', start_time), INTERVAL duration SECOND) < NOW()
ORDER BY CONCAT(date, ' ', start_time) DESC
LIMIT 1

У меня там есть предложение, предложение OR в квадратных скобках, которое не нужно. Я надеялся, что это может улучшить время запроса, сначала отфильтровывая любые «события», которые не начинаются сегодня или вчера. Единственный способ найти самое последнее «событие» - это упорядочить записи и взять первое. Добавляя это дополнительное ненужное предложение, я действительно сокращаю список записей, которые нужно упорядочить? Если это произойдет, я не могу представить, чтобы оптимизатор смог выполнить эту оптимизацию, большинство других вопросов, подобных этому, говорят об оптимизаторе.

Ответы [ 3 ]

2 голосов
/ 12 мая 2011

Будьте внимательны при добавлении фильтров в предложение WHERE для повышения производительности. Хотя это может уменьшить общее количество строк, которые необходимо найти, сам по себе фильтр может привести к более высокой стоимости, если он фильтрует тонну записей и не использует индекс. В вашем случае, если дата столбца проиндексирована, вы, вероятно, получите лучшую производительность, потому что она может использовать индекс в части ИЛИ, а не в других частях, потому что она вызывается как функция. Кроме того, вы можете иметь будущие даты? Если нет, почему бы вам не изменить ИЛИ на

date > DATE_SUB(CURDATE(), INTERVAL 1 DAY)
1 голос
/ 12 мая 2011

Что ж, оптимизатор в обработчике запросов - это большая часть производительности любого запроса или относительной производительности двух эквивалентных операторов.

Вы не сказали нам, выполняли ли вы запрос с или бездополнительно где.Может быть разница в производительности, а может и нет.

Я предполагаю, что LIMIT имеет к этому непосредственное отношение.Двигатель знает, что это операция «все готово».Без WHERE сортировка является операцией NlogN, которая в этом особом случае может быть сделана линейной с помощью простого сканирования дат, чтобы найти самые последние.

С WHERE вы фактически увеличиваете числошаги, которые он должен выполнить;либо он должен полностью упорядочить таблицу (NlogN), а затем отсканировать этот список для первой записи, которая соответствует предложению WHERE (линейный наихудший случай, постоянный наилучший случай), ИЛИ он должен отфильтровать по WHERE (линейный), затемСканируйте эти записи снова, чтобы найти максимальную дату (снова линейную).Какой бы из них ни оказался быстрее, они оба медленнее, чем одно линейное сканирование списка за последнюю дату.

1 голос
/ 12 мая 2011

Порядок предложения where влияет на то, как движок sql получает результаты.

Многие из них имеют способ посмотреть, что движок делает с запросом.Если вы используете sqlserver, поищите «показать примерный план выполнения» в вашем клиентском инструменте.У некоторых есть глагол типа «объяснить», который может использоваться, чтобы показать, как механизм обрабатывает запрос.

...