Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > СУБД, общие вопросы > Построить SQL запрос


Автор: Akina 24.5.2006, 11:05
Имеется 2 таблицы.

Таблица 1 (Name = DT) - результаты измерения датчиков.

Код

Имя поля   Тип поля   Комментарий
ID         Counter    Уникальный идентификатор
DDT        DataTime   Штамп времени записи
CatID      LongInt    ID категории события (внешний ключ)
DV         Double     Значение измерения

Первичный индекс - конкатенация полей DDT и CatID. 
Для каждого CatID значения DV являются монотонно возрастающими по времени, т.е. если DDT1>DDT2, то гарантированно DV1>DV2.

Таблица 2 (Name = TT) - весовые коэффициенты измерений.

Код

Имя поля   Тип поля   Комментарий
ID         Counter    Уникальный идентификатор
TDT        DataTime   Штамп времени записи
CatID      LongInt    ID категории события (внешний ключ)
TV         Double     Значение весового коэфф. измерения

Первичный индекс - конкатенация полей TDT и CatID.

CatID обоих таблиц ссылается на одну и ту же таблицу.

Штампы времени в таблицах по каждой категории выглядят так:
Код

DT *----*-----*----*-----*------*---*----*-- 
TT *------------*---------------*-----------

т.е. штамп времени начала гарантированно совпадает, промежуточные могут совпадать, могут НЕ совпадать, последний штамп времени таблицы DT заведомо позднее поледнего штампа времени таблицы TT.

Задача: получить выборку, содержащую след. данные:

DDT
CatID
DV
DeltaDV
 (изменение DV по отношению к предыдущему по штампу времени значению в той же категории)
TV (действующий на момент измерения весовой коэффициент)

Вроде ничего особо сложного, если бы не одно маленькое НО - количество записей. А именно порядка 5-10 млн. в DT и 1-2 млн. в TT.

Есть ли возможность выкрутиться? 

Автор: skyboy 24.5.2006, 11:41
Никаких ограничений нет? так даже выбор из одной таблицы 5-10 млн записей никак не может происходить быстро. И какая связь между указанными таблицами? Куда ссылается внешний ключ СatID? 

Автор: Akina 24.5.2006, 12:18
Цитата(skyboy @  24.5.2006,  12:41 Найти цитируемый пост)
Никаких ограничений нет?

нет 

Цитата(skyboy @  24.5.2006,  12:41 Найти цитируемый пост)
даже выбор из одной таблицы 5-10 млн записей никак не может происходить быстро.

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

Цитата(skyboy @  24.5.2006,  12:41 Найти цитируемый пост)
какая связь между указанными таблицами?

Прямой - нет.

Цитата(skyboy @  24.5.2006,  12:41 Найти цитируемый пост)
Куда ссылается внешний ключ СatID?

На таблицу категорий. Считай что ее структура проста:
Код

Имя поля   Тип поля   Комментарий
CatID      Counter    Уникальный идентификатор
Name       String     Название категории

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

Автор: skyboy 24.5.2006, 12:32
Всё равно не понимаю, что тебе надо выдать... Как должна вернуться информация, если приведённые тобой таблицы не связываются "напрямую"?
А если используется "как сырец" на сервере - неужели будет обрабатываться каждый раз всё скопом? Или всё же по чём-то будет делать выбор? Если собираешь засыпать сервер обработкой 5-10 млн записей, у тебя есть большой.. просто преогромный шанс засыпать его-таки smile 

Автор: Akina 24.5.2006, 12:43
Цитата(skyboy @  24.5.2006,  13:32 Найти цитируемый пост)
не понимаю, что тебе надо выдать

Поясню дальнейшее - когда будет получена промежуточная таблица (не временная!), она будет обрабатываться группировкой записей по интервалам и подсчетом сумм в интервалах, после чего полученные суммы будут исследоваться на наличие гармонических колебаний. Т.е. будут искаться периодические составляющие процесса. Однако выборка получается один раз - в твердой копии, т.е. будет Insert Into, и потом она прогоняется через алгоритм немеряное количество раз с разными размерами интервала.
Дело в том что некоторые периоды, которые должны быть, уже известны заранее, и они будут пробоваться в первую очередь, лишь потом начинается неспешное сканирование всех возможных периодов... так вот - именно этот первичный результат надо дать быстро.

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

Автор: skyboy 24.5.2006, 14:43
Я, наверное, не с той ноги встал smile 
Цитата(Akina @  24.5.2006,  12:43 Найти цитируемый пост)
когда будет получена промежуточная таблица

- как эта самая таблица будет получаться? Из чего, из каких полей?
 

Автор: Akina 24.5.2006, 15:53
Цитата(skyboy @  24.5.2006,  15:43 Найти цитируемый пост)
как эта самая таблица будет получаться? Из чего, из каких полей?

Так вот ее и нужно получить. Из двух исходных. 

Автор: Sqlninja 24.5.2006, 23:47
Оптимизация этого запроса во многом зависит не столько от синтаксиса, сколько от физического окружения, то есть возможностей сервера. Какая БД и есть ли какие-то средства оптимизации запросов, например как Query Optimizer в Oracle? Там бы я использовал хэш-соединения, например. 

Автор: skyboy 25.5.2006, 00:09
Sqlninja, слу, если ты понял структуру хранимых данных - обьясни и мне, пожалуйста. А то я никак не пойму, как мы две абсолютно не связанные таблицы будем вместе смешивать smile Может, там можно изменить структуру - и всё будет пучком? 

Автор: Akina 25.5.2006, 08:30
Стурктуру изменить невозможно - таблицы пишутся недоступным для коррекции софтом.
Данные ложатся в БД формата MS Access.

Цитата(skyboy @  25.5.2006,  01:09 Найти цитируемый пост)
я никак не пойму, как мы две абсолютно не связанные таблицы будем вместе смешивать

Таблицы объединены единой осью времени. То есть события, отмечаемые в таблицах, происходят хотя и асинхронно, но параллельно. Вот их и надо совместить.

Представь себе что это ОДНА таблица следующей структуры:
Код
Имя поля   Тип поля   Комментарий
ID         Counter    Уникальный идентификатор
DT         DataTime   Штамп времени записи
CatID      LongInt    ID категории события (внешний ключ)
DV         Double     Значение измерения
TV         Double     Значение весового коэфф. измерения
причем в каждой отдельной записи либо DV, либо TV содержит Null, а другое поле содержит значение, описанное выше.
 

Автор: Sqlninja 25.5.2006, 10:17
Цитата(skyboy @  25.5.2006,  00:09 Найти цитируемый пост)
Sqlninja, слу, если ты понял структуру хранимых данных - обьясни и мне, пожалуйста. А то я никак не пойму, как мы две абсолютно не связанные таблицы будем вместе смешивать 


Таблицы связываются по CatID. Для одинаковых CatID вычисляется разница во времени.


Цитата(Akina @  24.5.2006,  11:05 Найти цитируемый пост)
Вроде ничего особо сложного, если бы не одно маленькое НО - количество записей. А именно порядка 5-10 млн. в DT и 1-2 млн. в TT.

Есть ли возможность выкрутиться?  


Я так понял, что построить запрос Вы и сами сможете. То есть проблема в количестве записей? Тогда, если Ваш софт недоступен для коррекции, напишите свою утилитку, которая будет раз в час, например, делать INSERT в нужную Вам таблицу SELECT из Ваших 2х таблиц. Будет запоминаться штамп времени последнего такого "экспорта".

Если Вам нужны данные за прошлые периоды - ну что же, пусть этот запрос выполнится один раз очень долго, день или сколько там нужно времени. 

Автор: Akina 25.5.2006, 12:58
Цитата(Sqlninja @  25.5.2006,  11:17 Найти цитируемый пост)
если Ваш софт недоступен для коррекции, напишите свою утилитку, которая будет раз в час, например, делать INSERT в нужную Вам таблицу SELECT из Ваших 2х таблиц

Все не так.

Запускается эксперимент. С него накапливаются выходные данные в БД указанной структуры. Сразу по окончании эксперимента должна пойти обработка, которая должна сравнительно быстро (10-15 минут) дать результаты первичной обработки.

В общем, похоже, никто пока не может предложить решения в рамках SQL. Я его тоже найти пока не могу. Значит, будем обрабатывать программно. 

Автор: Cashey 26.5.2006, 12:01
Цитата(Akina @  24.5.2006,  13:43 Найти цитируемый пост)
Поясню дальнейшее - когда будет получена промежуточная таблица (не временная!),

Если, как я понял, будет промежуточная таблица с отфильтрованным набором данных, то может разумней провести все вычисления прям на серваке (а не посети) в хранимых процедурах, например. А уже к полученной таблице строить дальнейший запрос для обработки данных уже с клиента 

Автор: Akina 26.5.2006, 12:04
Cashey
Собственно, именно это и сделано. Просто хотелось остаться в рамках SQL и не строгать процедур. Не вышло - ну да и хрен бы с ею... 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)