powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Индекс не использует при применении функции
9 сообщений из 9, страница 1 из 1
Индекс не использует при применении функции
    #39965944
Фотография Megabyte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллеги, всем привет.

Есть таблица условно:
Код: sql
1.
2.
3.
4.
5.
CREATE TABLE tmp(
id int,
start datetime,
timezone int
)



Для фильтра по dt и timezone делаю индекс:
Код: sql
1.
CREATE INDEX IX_tmp_start_timezone ON tmp(start, timezone)



Условный запрос:
Код: sql
1.
2.
3.
SELECT ID
FROM tmp g
WHERE ( DATE_ADD(g.start, INTERVAL 3-g.timezone HOUR)  >'2020-05-06') AND ( DATE_ADD(g.start, INTERVAL 3-g.timezone HOUR) <'2020-05-27')


Индекс не используется.
Переписал так:
Код: sql
1.
2.
3.
SELECT ID
FROM tmp g
WHERE (g.start > DATE_ADD('2020-05-06', INTERVAL g.timezone-3 HOUR)) AND (g.start < DATE_ADD('2020-05-27', INTERVAL g.timezone-3 HOUR))


Индекс так же не используется.
Пробовал делать индекс чисто по start. Все равно не используется.

Есть варианты заставить использовать индекс или они в принципе с функциями не дружат? Или все норм, а я что-то не так делаю\не так проверяю... Большой объем данных не генерил. Но сделал, чтобы выбираемые данные занимали малый % от общего числа.
---
Проходя мимо разложенных граблей, ты теряешь драгоценный опыт. (с)
...
Рейтинг: 0 / 0
Индекс не использует при применении функции
    #39966021
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Индекс НЕ МОЖЕТ использоваться в указанных запросах. Поле должно быть "чистым".

Создай вцчисляемое поле

Код: sql
1.
start_w_timezone AS ( DATE_ADD(g.start, INTERVAL 3-g.timezone HOUR)  )


и индекс по нему, и используйте его в запросе.

Если версия позволяет, поле создайте VIRTUAL...
...
Рейтинг: 0 / 0
Индекс не использует при применении функции
    #39966070
Фотография Megabyte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina
Индекс НЕ МОЖЕТ использоваться в указанных запросах. Поле должно быть "чистым".

Создай вцчисляемое поле

Код: sql
1.
start_w_timezone AS ( DATE_ADD(g.start, INTERVAL 3-g.timezone HOUR)  )


и индекс по нему, и используйте его в запросе.

Если версия позволяет, поле создайте VIRTUAL...

Прошу прощения, не дописал, 3(в выражении 3-g.timezone) - в данном случае, входной параметр таймзона.
Поэтому вычисляемое поле нельзя сделать заранее.

Во втором случае же поле start "чистое", не? Это выражение для сравнения вычисляемое...
...
Рейтинг: 0 / 0
Индекс не использует при применении функции
    #39966149
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Megabyte
3(в выражении 3-g.timezone) - в данном случае, входной параметр таймзона.
Поэтому вычисляемое поле нельзя сделать заранее.
Что именно есть параметр? я вижу в выражении два поля одной и той же записи. И у меня в выражении для вычисляемого поля - те же два поля в том же самом выражении.

Megabyte
Во втором случае же поле start "чистое", не?
А у тебя что, индекс только по полю start? или таки не?
...
Рейтинг: 0 / 0
Индекс не использует при применении функции
    #39966194
Фотография Megabyte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina
Megabyte
3(в выражении 3-g.timezone) - в данном случае, входной параметр таймзона.
Поэтому вычисляемое поле нельзя сделать заранее.

1) Что именно есть параметр? я вижу в выражении два поля одной и той же записи. И у меня в выражении для вычисляемого поля - те же два поля в том же самом выражении.

Megabyte
Во втором случае же поле start "чистое", не?

2) А у тебя что, индекс только по полю start? или таки не?

1)
Код: sql
1.
2.
3.
SELECT ID
FROM tmp g
WHERE ( DATE_ADD(g.start, INTERVAL param-g.timezone HOUR)  >'2020-05-06') AND ( DATE_ADD(g.start, INTERVAL param-g.timezone HOUR) <'2020-05-27')


где param - это параметр

аналогично в этом варианте:
Код: sql
1.
2.
3.
SELECT ID
FROM tmp g
WHERE (g.start > DATE_ADD('2020-05-06', INTERVAL g.timezone-param HOUR)) AND (g.start < DATE_ADD('2020-05-27', INTERVAL g.timezone-param HOUR))



2) Пробовал и индекс по паре start, timezone, так и чисто по start. Не хочет юзать. :(
В конечном запросе у меня там еще 2 джойна. Не знаю, может это влияет на использование индекса по start.

Полный запрос такой:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT 
  DATE_ADD(g.start, INTERVAL 3-g.timezone HOUR) as start, 
  DATE_ADD(g.end, INTERVAL 3-g.timezone HOUR) as end, 
  g.title, 
  g.series/*,
  c.id_str, 
  c.name, 
  churl, 
  c.ico*/ 
  -- ,a.fullurl 
  ,g.channelid
FROM tbl g 
  INNER JOIN tbl2 c ON c.id = g.channelid 
  LEFT JOIN tbl3 a ON g.anons_id = a.id
 WHERE (g.start > DATE_ADD('2020-05-04', INTERVAL g.timezone-3 HOUR)) AND (g.start < DATE_ADD('2020-05-08', INTERVAL g.timezone-3 HOUR))
ORDER BY c.sort, g.start
...
Рейтинг: 0 / 0
Индекс не использует при применении функции
    #39966223
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Megabyte,

как уже заметили, чтобы заюзать индекс надо сравнивать поле с константой (константой может быть и выражение, которое вычисляется единожды)

Код: sql
1.
DATE_ADD(g.start, INTERVAL param-g.timezone HOUR)  >'2020-05-06')


поясни словами чего хочешь добиться, может обходные пути подскажут
...
Рейтинг: 0 / 0
Индекс не использует при применении функции
    #39966591
Фотография Megabyte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дегтярев Евгений
Megabyte,

как уже заметили, чтобы заюзать индекс надо сравнивать поле с константой (константой может быть и выражение, которое вычисляется единожды)

Код: sql
1.
DATE_ADD(g.start, INTERVAL param-g.timezone HOUR)  >'2020-05-06')


поясни словами чего хочешь добиться, может обходные пути подскажут

Уже нашел сам вариант.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
SELECT SQL_NO_CACHE
  DATE_ADD(g.start, INTERVAL 3-g.timezone HOUR) as start, 
  DATE_ADD(g.end, INTERVAL 3-g.timezone HOUR) as end, 
  g.title, 
  g.series,
  g.channelid,
  g.anons_id
FROM
  (
    SELECT
      start,
      end,
      timezone,
      title,
      series,
      channelid,
      anons_id           
    FROM tmp t
    WHERE (t.start > DATE_ADD('2020-04-29 00:00:00', INTERVAL -1 DAY)) AND (t.start < DATE_ADD('2020-04-29 23:59:59', INTERVAL 1 DAY))
  ) g
WHERE (g.start > DATE_ADD('2020-04-29 00:00:00', INTERVAL g.timezone-3 HOUR)) 
   AND (g.start < DATE_ADD('2020-04-29 23:59:59', INTERVAL g.timezone-3 HOUR))



Делаю подзапросом +- 1 день, чтоб зацепить все часовые зоны. Тогда цепляется индекс. А потом уже по получившемуся делаю нужный фильтр.

Всем спасибо.
...
Рейтинг: 0 / 0
Индекс не использует при применении функции
    #39966643
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
жаль, мы так и не узнали сакрального смысла этого костыля
...
Рейтинг: 0 / 0
Индекс не использует при применении функции
    #39966672
Фотография Megabyte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дегтярев Евгений
жаль, мы так и не узнали сакрального смысла этого костыля

Я не автор. Мне надо было лишь оптимизировать.
Возможно, проблемы с бизнес-логикой и есть. Но меня лично интересовал только момент с функцией и индексом.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Индекс не использует при применении функции
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]