Комментарии 5
Эта задача решается быстрее на Oracle, чем на MS SQL
Любая задача быстрее решается тем инструментом, которым лучше владеешь. Бегло посмотрел код на MSSQL — мне кажется там много где можно докрутить — типы курсоров, оконные функции, детерминирование функции TRUNC_UT и т.д. А вообще задача довольно простая — зачем так много вариантов перебирать и сравнивать сервера — что в итоге хотели получить?
+1
зачем так много вариантов перебиратьКогда запрос выполняется 5 секунд, его, разумеется, никто не станет оптимизировать.
Но если запрос выполняется час или день — полагаю, у каждого
разработчика БД или DBA возникнет вопрос, а можно ли его оптимизировать?
и сравнивать сервераПросто есть опыт 4.5 года и на MS SQL, запустил и там. Цели «сравнить» не было
посмотрел код на MSSQL — мне кажется там много где можно докрутитьВозможно код, возможно сервер, но кроме оконных функций
0
Оконные функции использовать можно в подобных запросах — в этом случае можно не делать соединения таблицы самой с собой — иногда это выгодно. Вопрос производительности — это уже другой вопрос.
Скорее всего на практике вам не потребуются все данные, а только определённый объём за период и по определённому таймфрейму — это может привести совсем к другим показателям.
И очень странные результаты тестирования варианта CALC — как может вариант, где всё заранее посчитано и сложено в таблицу медленнее какого-то другого?
И ещё вот тут — min (1000000 * cast (UT as bigint) + ID) — маловато будет смещение для 11 млн записей. Да и не нужно такие сложности — достаточно просто min(ID) сделать.
Скорее всего на практике вам не потребуются все данные, а только определённый объём за период и по определённому таймфрейму — это может привести совсем к другим показателям.
И очень странные результаты тестирования варианта CALC — как может вариант, где всё заранее посчитано и сложено в таблицу медленнее какого-то другого?
И ещё вот тут — min (1000000 * cast (UT as bigint) + ID) — маловато будет смещение для 11 млн записей. Да и не нужно такие сложности — достаточно просто min(ID) сделать.
0
Оконные функции использовать можно в подобных запросахУбедил. Я написал вариант WIND для двух движков. Но чтобы его протестировать на производительность нужно время. Наверное, в выходные. Ранее меня пугало слово distinct, я считал, что это будет лишний шаг. Если получу удовлетворительные результаты — я добавлю в пост в пул вариантов с указанием ссылки на тебя. Годится? Или можешь опубликовать его здесь сам.
Скорее всего на практике вам не потребуются все данные, а только определённый объёмТут, также как в DWH. Действительно, в каждый конкретный момент времени нам требуется небольшой кусочек данных, но за день окажется что мы опросили большую часть всего объёма, и некоторые части — многократно (и многократно же их рассчитывали). Чтобы не тратить время на многократный расчёт — мы загружаем в хранилище все данные, за весь период, и рассчитав однократно.
как может вариант, где всё заранее посчитано и сложено в таблицу медленнее какого-то другого?Почему? Он не медленнее, он быстрее всего на MS SQL.
?
Можешь связаться со мной, обсудим, отвечу на вопросы
достаточно просто min(ID) сделатьЭто моя ошибка. Я исправлю. Просто ранее это поле называлось не ID, а SEQ_NUM, и в нём хранился порядковый номер транзакции внутри секунды. Там окна 10^6 было с запасом. Но потом я отказался от этого поля, потому что требовался дополнительный оператор, который пройдёт по всей таблице и заполнит это поле на основании ID
0
Хороших результатов с оконными функциями я не добился на MSSQL, так что в данном случае особенно выкладывать думаю нечего и тратить на это время тоже — использование внутри функции расчёта таймфрейма для PARTITION BY несколько раз для каждой цены свечки — не самый хороший вариант:
Тут наверное нужно делать предварительный расчёт даты/времени в отдельных колонках таблицы для каждого таймфрейма и потом уже пользоваться ими в запросе.
Вобщем не самый оптимальный вариант.
Что касается скорости метода CALC — то я имел в виду ORACLE — он оказался чуть ли не на последнем месте — просто не хватило индексов в таблице?
DECLARE @STRIPE_ID int = 5
SELECT dbo.UT2DATESTR(UT), *
FROM (
SELECT STRIPE_ID = @STRIPE_ID,
STOCK_NAME,
dbo.TRUNC_UT(UT, @STRIPE_ID) AS UT,
AOPEN = FIRST_VALUE(APRICE) OVER (PARTITION BY dbo.TRUNC_UT(UT, @STRIPE_ID) ORDER BY UT),
ACLOSE = LAST_VALUE(APRICE) OVER (PARTITION BY dbo.TRUNC_UT(UT, @STRIPE_ID) ORDER BY UT RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
AMAX = MAX(APRICE) OVER (PARTITION BY dbo.TRUNC_UT(UT, @STRIPE_ID) ORDER BY UT RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
AMIN = MIN(APRICE) OVER (PARTITION BY dbo.TRUNC_UT(UT, @STRIPE_ID) ORDER BY UT RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
SORT = ROW_NUMBER() OVER (PARTITION BY dbo.TRUNC_UT(UT, @STRIPE_ID) ORDER BY UT ASC),
CNT = COUNT(*) OVER (PARTITION BY dbo.TRUNC_UT(UT, @STRIPE_ID)),
APRICE
FROM TRANSACTIONS_RAW) x
WHERE x.SORT = 1
Тут наверное нужно делать предварительный расчёт даты/времени в отдельных колонках таблицы для каждого таймфрейма и потом уже пользоваться ими в запросе.
Вобщем не самый оптимальный вариант.
Что касается скорости метода CALC — то я имел в виду ORACLE — он оказался чуть ли не на последнем месте — просто не хватило индексов в таблице?
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Прореживание таймфреймов (криптовалюты, форекс, биржи)