crower: (Default)
[personal profile] crower

С оптимизацией получился облом.

Напомню, что была попытка соптимизировать запрос с select ... where date(field) in (...) group by .... Я в курсе, что конструкция field in (...) сама по себе дорогая, но вполне приемлема, если потеря скорости незначительна, а альтернатива может оказаться ещё дороже.

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

Попробовал другое "дешёвое" решение — внедрить ограничение диапазона, где код where date(field)≥{min_time} and date(field)<{max_time} призван был сократить первоначальную выборку, и уже после этого работал бы var in (...). Нужно было планчик составить, но лениво. А потом оказалось что и var in лишний. С выборкой нужных дат в самом скрипте всё оказалась гораздо быстрее. И поначалу всё заработало как надо. И дело даже не в кешировании. Потому как регулярно, раз в час поступают новые данные.

Эффект был кажущимся из-за того, что на момент тестирования дат было не так много и group by на все эти даты не сильно тормозил. Но наступление события "С", ради которого весь этот сыр-бор, задержалось. И получилось что между первой и последней датой времени прошло настолько много, что быстродействие от экономии на отказе от var in полностью пожралось group by. Долгим и бессмысленным.

Ещё бы:

  • 4 таблицы: 1.2млн, 1.3млн, 26млн и 27млн записей.
  • интересующие данные (без уточнения по дате) составляют 64К, 10К, 130К и 20К записей.
  • в таблицах сидит timestamp, а выборку и результат нужно делать от функции по нему. Хоть через substr, хоть по date.

Можно было плюнуть и вернуться к старой схеме, но "мы не привыкли отступать"© и это оскорбляет эстетическое чувство.

Поэтому пришлось делать красиво и по-полной схеме. При обращении к странице, скрипт запрашивает данные, уже сгруппированные по дате и лежащие в специальной дочерней таблице. Если на определённую дату данных нет, то запрашиваются данные в родительской таблице. Если они оказываются полными за указанную дату (24 часа, 1440 минут или 86400 минут), то они вставляются в дочернюю таблицу и в следующий раз будут извлекаться оттуда. Считать их заново будет не нужно. Операция сия была необходима для одного определённого объекта, так что пухнуть дочерние таблицы не будут. При периодическом опросе данные за прошедшие дни обстчитываются постепенно, и только за текущий - постойнно. В результате подтормаживание составляет при пересчёте прошедших суток считанные доли секунды, а за текущую дату - даже не заметно. Всё-таки выборка по timestamp ≥ {time} and (timestamp < {time} + INTERVAL 1 DAY) гораздо быстрее, чем упоминавшиеся ранее конструкции. Да и group by нужно будет убрать, т.к. алгоритм и ткак каждый раз выдёргивает по одной строке.

Зато теперь всё классно. :)

From:
Anonymous( )Anonymous This account has disabled anonymous posting.
OpenID( )OpenID You can comment on this post while signed in with an account from many other sites, once you have confirmed your email address. Sign in using OpenID.
User
Account name:
Password:
If you don't have an account you can create one now.
Subject:
HTML doesn't work in the subject.

Message:

 
Notice: This account is set to log the IP addresses of everyone who comments.
Links will be displayed as unclickable URLs to help prevent spam.

Profile

crower: (Default)
crower

September 2017

S M T W T F S
     12
3456789
10111213141516
17 181920212223
24252627282930

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 20th, 2017 02:39 pm
Powered by Dreamwidth Studios