Срочно нужно получить результаты "большого запроса" запроса

rock-n-roll
Дата: 18.12.2012 15:09:40
Доброго времени суток. Нужен срочный хелп.
такой запрос
SELECT a.schet,a.filter_uch,a.id,MAX(a.sum) as sum,MAX(a.opl) as opl,SUM(NVL(b.sum, 0)) as temp,000000.00 as dolg;
FROM zzzzz3 a LEFT OUTER JOIN zzzzz3 b ON b.id<a.id group by a.id,a.schet,a.filter_uch into CURSOR  zzzzz4

Запрос "нормальный" те на тестовых данных все впоряде, но на реальной базе пишет что слишком большой темп файл.


Что можно сделать.машина на которой выполняется 2Га ОЗУ, винт вообще терабайтник,NTFS
Что б сдесь можно было сделать-неважно пусть час выполняется запрос -нужен результат
miv32
Дата: 18.12.2012 15:50:37
1) Неудачный алиас столбца - "Temp"
2) Сомнительная связка таблицы саму с собой. Как результат - декартово произведение.
По моему - полная хрень.
rock-n-roll
Дата: 18.12.2012 15:54:57
Не помню от куда взял на вооружение... эта хрень есть нарастающий итог на небольших исходнных нормально работает.
Может есть другие варианты?
Jonny540
Дата: 18.12.2012 16:20:44
rock-n-roll
... эта хрень есть нарастающий итог...
Что ты имеешь ввиду под "нарастающий итогом"? Если можно, поподробнее, а то есть разные варианты.
ВладимирМ
Дата: 18.12.2012 16:36:49
Ну, то, что Вы вышли за пределы системных ограничений FoxPro не удивительно. Напомню, что FoxPro ограничивается размером таблицы в 2ГБ или количеством записей в 1 миллиард (1 и 9 нулей). Смотря что раньше кончится. У Вас декартово произведение. Т.е. надо возвести в квадрат количество записей исходной таблицы. Вот и смотрите, какой размер и количество записей получилось.

А решение очевидное. Отказаться от Select-SQL и перейти к сканированию

* Предварительная выборка решает несколько задач
* Формирует итоговый курсор нужной структуры
* и упорядочивает записи таким образом, чтобы записи одной группы 
* оказались рядом и в нужной последовательности (order by)
select 
        a.schet, ;
        a.filter_uch, ;
        a.id, ;
        a.sum, ;
        a.opl, ;
        a.sum - a.sum as temp, ;
        000000.00 as dolg ;
from zzzzz3  ;
into cursor zzzzz4 readwrite ;
order by 1,2,3

local lvSchetPrev, lvFilter_uchPrev, lvIdPrev, lnSumGroup
* Даю переменным пустые значения, заведомо не существующие в таблице, но нужного типа
* это необходимо для корректного входа в цикл
lvSchetPrev = ''
lvFilter_uchPrev = ''
lvIdPrev = 0

* Собственно расчет нарастающего итога
* Для первой строки группы нарастающий итог остается равным нулю
select zzzzz4
go top
scan
    if m.lvSchetPrev <> zzzzz4.Schet OR m.lvFilter_uchPrev <> zzzzz4.Filter_uch OR m.lvIdPrev <> zzzzz4.Id
        m.lvSchetPrev = zzzzz4.Schet 
        m.lvFilter_uchPrev = zzzzz4.Filter_uch 
        m.lvIdPrev = zzzzz4.Id
        m.lnSumGroup = zzzzz4.Sum
    else
        replace temp with m.lnSumGroup
        m.lnSumGroup = m.lnSumGroup + zzzzz4.Sum
    endif
endscan
AndreTM
Дата: 18.12.2012 16:38:54
Это не "нарастающий итог" в общем случае. Посмотрите на выборку
SELECT a.id as a_id, b.id as b_id, NVL(b.sum,0) as temp;
 FROM zzzzz3 a LEFT OUTER JOIN zzzzz3 b ON b.id<a.id;
 INTO CURSOR zzzzz4a
и поймёте, что, при наличии нескольких записей с одинаковым Id - LEFT JOIN повторит предыдущие Id столько раз, сколько у вас записей с текущим Id... Кроме того, нарастающий итог, ИМХО, имеет смысл только при наличии упорядоченных записей, а что такое Id - неизвестно, и в каком порядке нужно наращивать итог - непонятно.

Проще для получения нарастающего итога не делать один селект, а сделать выборку и пройтись по ней SCANом.
AndreTM
Дата: 18.12.2012 16:40:26
Упс... (я так понимаю, мысли сходятся...)
rock-n-roll
Дата: 18.12.2012 17:04:45
Угу спс спс спс