|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Всем привет! Есть подобная таблица: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
В данном примере: USERID->1 был 5 раз (на TARIFID->5) Сейчас используется ресурсоемкий алгоритм (stored procedure), который в лоб перебирает записи. Надо как-то оптимизировать. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2019, 16:30 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1Сейчас используется ресурсоемкий алгоритм (stored procedure), который в лоб перебирает записи. Надо как-то оптимизировать. Используй курсор и выбирай только последние записи для каждого пользователя. Возможно, пригодится убывающий индекс по USERID, DATE. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2019, 16:41 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1, и где же запрос, который надо оптимизировать? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2019, 16:46 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
Модератор: используйте теги! ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2019, 17:00 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1, неизвестна версия ФБ. В данном примере 7 записей, а не пять. И что такое последний TARIFID? Максимальный номер? Или последний по дате? Есть ещё таблицы? Если существует только одна плоская таблица, то скорее всего удастся только отсечь по датам. Остальное придётся перебирать в лоб. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2019, 17:20 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1, без процедур где-то так Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2019, 18:28 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
неизвестна версия ФБ. 2.5.2 В данном примере 7 записей, а не пять. Нужно посчитать непрерываемую последовательность, от текущего дня к "прошлому" - сколько дней на текущем TARIFID И что такое последний TARIFID? Максимальный номер? Или последний по дате? INTEGER, по последней дате Есть ещё таблицы? Нет авторЕсли существует только одна плоская таблица, то скорее всего удастся только отсечь по датам. Важны не даты, а сколько пробыл на текущем TARIFID авторОстальное придётся перебирать в лоб. Это я и так делаю, думал оптимизировать. За остальные примеры спасибо, примерю их, отпишусь. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2019, 19:25 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
"Ресурсоёмкий алгоритм", который перебирает записи с конца - самый простой и быстрый. Но можно и запросом. Код: sql 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 08:55 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1Есть ещё таблицы? Нет авторЕсли существует только одна плоская таблица, то скорее всего удастся только отсечь по датам. Важны не даты, а сколько пробыл на текущем TARIFID авторОстальное придётся перебирать в лоб. Это я и так делаю, думал оптимизировать. А что таблица совсем гигантская? Сколько записей в таблице за заданный период? В плоской таблице мало путей для оптимизации. Надо наверно оставить как есть. И посмотреть индексы по датам. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 10:36 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
KreatorXXI, Немного вроде, порядка ~60 млн записей. Индексы по ключевым значениям есть. Данные статистические, не очень критичные, требуются для человека. Сейчас эта статистика собирается раз в сутки, на это уходит минут ~40. Думаю сделать этот расчет по запросу, по конкретному USERID, т.к. 100% покрытие статистикой совершенно не требуется, а значит зазря 40 минут в день теряются в подсчетах. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 11:34 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1KreatorXXI, Немного вроде, порядка ~60 млн записей. Индексы по ключевым значениям есть. Данные статистические, не очень критичные, требуются для человека. Сейчас эта статистика собирается раз в сутки, на это уходит минут ~40. Думаю сделать этот расчет по запросу, по конкретному USERID, т.к. 100% покрытие статистикой совершенно не требуется, а значит зазря 40 минут в день теряются в подсчетах. денормализация. агрегаты. отдельная табличка - UserID, MAX_COUNT, TariffID, DateLastCheck. пересчитывать на после даты. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 11:43 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1, Это за какой период 60 млн? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 11:50 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1требуются для человека. Таки определитесь для начала: требуются на одного человека или на каждого? И насколько часто? Для первого случая и частоты запросов менее раза в секунду - цикл при правильном плане самое лучшее решение. Хранимые агрегаты, конечно, тоже можно сделать, но там есть грабли. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 11:54 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Это за какой период 60 млн? Это за 13 лет, в статистике участвуют последние 5. Таки определитесь для начала: требуются на одного человека или на каждого? И насколько часто? Для первого случая и частоты запросов менее раза в секунду - цикл при правильном плане самое лучшее решение. Статистические данные нужно показать оператору(ам), когда тот открывает карточку USERID. Менее раза в секунду, конечно же. Пока склоняюсь к созданию процедуры GET_USER_TARIF_DAYS(:USERID), которая в лоб будет считать, но только одного USERID. И конечно же нужна отдельная табличка, как правильно написал pastor , которая будет следить за состоянием статистики, если сегодня уже считали - на готовый результат. Не считали - считаем, сохраняем, возвращаем. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 12:12 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1Это за 13 лет, в статистике участвуют последние 5. зачем постоянно пересчитывать неизменяемые, архивные данные? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 12:35 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1Пока склоняюсь к созданию процедуры GET_USER_TARIF_DAYS(:USERID), которая в лоб будет считать, но только одного USERID. Пока это количество дней нужно только для карточки, это наилучший вариант. Rom1И конечно же нужна отдельная табличка, как правильно написал pastor, которая будет следить за состоянием статистики, если сегодня уже считали - на готовый результат. Не считали - считаем, сохраняем, возвращаем. А вот это пока что выглядит совершенно избыточным. Оно бы потребовалось при десятках-сотнях запросов в секунду по отдельным пользователям или при довольно частом запросе по всем миллионам пользователей. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 12:38 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
зачем постоянно пересчитывать неизменяемые, архивные данные? Тогда придется заниматься аггрегацией, а за ней придется следить. А это значит что нужно сразу приготовить отходные пути по перерасчету всей аггрегации, в случае ошибок/поломок/недоверия консистетности. А вот это пока что выглядит совершенно избыточным. Оно бы потребовалось при десятках-сотнях запросов в секунду по отдельным пользователям или при довольно частом запросе по всем миллионам пользователей. Да, эта информация показывается еще в некоторых местах (группа USERIDs, до 100 штук), там AJAX'ом будет подгружаться уже эта статистика по каждому USERID. Дважды открылась группа - это уже 200% подсчетов статистики, а можно гарантированно остановиться на 100%. Так что такое кеширование, думаю не лишним будет. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 12:55 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1Так что такое кеширование, думаю не лишним будет. Будет. Поэтому лично я бы с ним не связывался пока не пойдут жалобы на производительность. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 13:06 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
А хранили бы только изменения - достаточно было бы только одну последнюю запись взять для подсчёта. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 13:27 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1, зачем забивать таблицу избыточными данными по каждому дню, когда достаточно хранить лишь дату перехода пользователя на другой тариф? Самым оптимальным решением, на мой взгляд, является именно обход данных внутри ХП в курсоре FOR SELECT с упорядочением по полям идентификатора пользователя и даты смены тарифа, что позволяет обеспечить самый быстрый и удобный подсчёт кол-ва дней внутри каждого диапазона смены тарифов, а затем, из полученного в ХП набора данных, вычленить максимальное кол-во дней с группировкой по идентификатору пользователя и идентификатору тарифа. Ещё напрашивается вопрос - что делать, если два разных тарифа пользователя имеют одинаковый максимальный срок действия? Думаю, запрос будет работать медленнее, хуже пониматься разработчиками и смысл его создания - лишь спортивный интерес Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 13:59 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1зачем постоянно пересчитывать неизменяемые, архивные данные? Тогда придется заниматься аггрегацией, а за ней придется следить. А это значит что нужно сразу приготовить отходные пути по перерасчету всей аггрегации, в случае ошибок/поломок/недоверия консистетности. А вот это пока что выглядит совершенно избыточным. Оно бы потребовалось при десятках-сотнях запросов в секунду по отдельным пользователям или при довольно частом запросе по всем миллионам пользователей. Да, эта информация показывается еще в некоторых местах (группа USERIDs, до 100 штук), там AJAX'ом будет подгружаться уже эта статистика по каждому USERID. Дважды открылась группа - это уже 200% подсчетов статистики, а можно гарантированно остановиться на 100%. Так что такое кеширование, думаю не лишним будет. у меня так сейчас остатки на л/с клиентов хранятся. есть агрегат - берем его, делаем +-, переписываем агрегат. на время работы - select with lock. нет агрегата - считаем с нуля. вылезло на постоянных клиентах за много лет. для одного клиента в итоге приходится поднимать всю базу, т.к. он понемножку отметился на всех страницах данных. индексы проблемы не решают. побочный положительный эффект - блокировка л/с на момент транзакции. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 14:05 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1, зачем забивать таблицу избыточными данными по каждому дню, когда достаточно хранить лишь дату перехода пользователя на другой тариф? Это билинговая система. Есть таблица тарифных планов каждого USERID, там указаны как раз-таки периоды: TARIFID, начало-окончание/начало-бесконечность. Есть таблица реальных начислений, которые должны храниться и доставаться без каких либо вычислений - это требование аудита. При этом тарифы абонента со временим удаляются. Поэтому статистику о том сколько USERID находится на тарифном плане, можно поднять только из реальных начислений. Ещё напрашивается вопрос - что делать, если два разных тарифа пользователя имеют одинаковый максимальный срок действия? Максимальный срок действия тарифа - бесконечность (без ограничения). Есть стек тарифов, они накладываются друг на друга, одни имеют приоритет над другими, короче - это компиляция. Единственные простые, плоские данные, находятся в таблице реальных начислений. авторесть агрегат - берем его, делаем +-, переписываем агрегат. на время работы - select with lock. нет агрегата - считаем с нуля. Аггрегатом придется заниматься всегда и всегда помнить о нем и иметь отходные пути, которые не остановят работу на в ЧНН. Мне такая концепция не нравится. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 15:05 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1Аггрегатом придется заниматься всегда и всегда помнить о нем и иметь отходные пути, которые не остановят работу на в ЧНН. Мне такая концепция не нравится. пока не бросишь программирование. организуй в это место доступ через хп. у меня агрегаты еще имеют срок годности, после которого их требуется пересчитать. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 15:10 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Rom1Это за какой период 60 млн? Это за 13 лет, в статистике участвуют последние 5. Значит участвуют миллионов 20 записей. Если тупо пробежаться по ним, будет в районе двух минут (я бы даже дал меньше - полминуты). Скорее всего Вы своими наворотами всё портите. Как предложил Dimitry Sibiryakov, используйте запрос с курсором в хранимке. Или приведите свой запрос для начала. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 15:11 |
|
Помогите оптимизировать запрос
|
|||
---|---|---|---|
#18+
Значит участвуют миллионов 20 записей. Если тупо пробежаться по ним, будет в районе двух минут (я бы даже дал меньше - полминуты). Скорее всего Вы своими наворотами всё портите. Как предложил Dimitry Sibiryakov, используйте запрос с курсором в хранимке. Или приведите свой запрос для начала. Я конечно же задачу сократил до минимума, чтобы указать на суть расчета и связанной с этим проблемы. Собрать статистику, удалить данные, добавить - все это достаточно ресурсоемко, пол минуты - это тупо посчитать количество записей в начислениях, без обработки. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.07.2019, 15:25 |
|
|
start [/forum/topic.php?fid=40&fpage=21&tid=1560639]: |
0ms |
get settings: |
9ms |
get forum list: |
10ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
37ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
others: | 9ms |
total: | 134ms |
0 / 0 |