![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вопрос по SQL и Interbase. [D4, D5, IB5.x, ]
VL © (2001-12-27 10:49:00)Знатоки, может кто знает как решить проблему.
Посылается на сервер запрос
select * from <TABLE>
left join .....
left join .....
left join .....
where <......>
сей запрос считается 7 секунд.
Если вместо * указать sum(...), то он считается 30 сек.
Я, может по незнанию считал, что сумма должна считаться быстрее чем общая выборка.
Если возможность ускорить получение ответа по просчету.
Alexandr (2001-12-28 07:15:00) [1]конечно можно...
прявяжи к первому процессору и все хуже не станет, даже если второй уберешь.
VL (2001-12-27 17:28:00) [2]отменить (снять) потом привязку можно?
Alexandr (2001-12-27 15:04:00) [3]а ты не по счетчику смотри. Ты посмотри сколько у тебя под файловый кэш используется- это в счетчик не попадает.
Надо другие утилитки пробовать.
как насчет привязки? Без нее плохо очень.
VL (2001-12-27 15:00:00) [4]NT4
память по счетчику памяти не подымается выше половины.
Alexandr (2001-12-27 14:44:00) [5]нескромный вопрос: ты IB привязал к одному процессору?
нужна спец. утилита ibaffinity с ib.demo.ru
а ОС какая?
а вообще-то 256 метров маловато.
VL (2001-12-27 14:35:00) [6]256М 6нс dim"ы
raid масив высшей (0 или 5 непомню) категории 3 scsi винта 10700 об по 9Гб = 18 Гб пространства.
тачка двухпроцессорная 2 х 550M Xeon
Alexandr (2001-12-27 14:29:00) [7]ок.
неплохо...
а ОЗУ сколько на серваке?
VL (2001-12-27 14:28:00) [8]база - 550 М
Database cashe = 8192
client map size = 8192
Alexandr (2001-12-27 14:20:00) [9]database cache- это кэш страниц базы данных в памяти.
Больше 1000 тысяч ставить не надо- это плохо.
Если это число умножить на размер страницы - то будет объем ОЗУ
при этом размер страницы может быть 1024,2048, 4096,8192 байта.
Еще рекомендуют размер страницы выбирать такой-же как размер кластера на винте.
А лучше всего пробовать...
почитай еще на ib.demo.ru есть статьи по поводу повышения быстродействия.
а так могу посоветовать поставить где-то 2000 страниц в database cache. Это обычно оптимально.
Кстати, а размер базы данных, размер страницы в базе у тебя какой?
GreySerg (2001-12-27 14:11:00) [10]Natural означает, что выполняется перебор всех записей, без использования индексов
VL (2001-12-27 14:06:00) [11]Дело в том, что я делал сумирование в процедуре - это тоже самое время, что и sum в запросе. Исходя из экспериментов, он действительно при select * from ... передает на клиента часть вырорки. Я делал в процедуре for select * from .... do sum=sum+<данные> - время просчета тоже, что и сумирование в запросе.
Обьясните бестолковому, что такое NATURAL.
Вопрос по Interbase 5.6: есть в настройках параметров сервера два параметра Database cashe, client map size. На что они влияют?
Alexandr (2001-12-27 14:01:00) [12]не спорю.
лучше использовать процедуру.
Но не обижаться если это выйгрыша в быстродействии не даст.
Romkin (2001-12-27 13:58:00) [13]Полностью согласен, но sp работает все же быстрее (с условием), тк процедура компилится, и план уже есть. А явное суммирование - просто удобно, можно проверять дополнительные условия перед суммированием, избегать выдачи нулевых сумм и проч. Возможно, еще и тормоза из-за большого выражения под суммой, да еще из разных таблиц
Alexandr (2001-12-27 13:48:00) [14]какая разница избежать или не избежать
подумай: принцип-то тот же - проходим по всем записям и суммируем
пусть в процедуре будет sum=sum+inc_sum;
это же тоже самое по вычислительным ресурсам.
Чудес не бывает...
Romkin (2001-12-27 13:39:00) [15]Естественно, но если делать в процедуре - там оператора sum можно избежать (хотя и необязательно, просто я так привык), а план контролировать для условий выбора
Alexandr (2001-12-27 13:38:00) [16]выход один- смотреть чего серваку не хратает и ставить быстрее диск, мощнее процессор, больше памяти и пр.
Если уж так критично...
Alexandr (2001-12-27 13:36:00) [17]обратите внимание же что у него так или иначе sum
а как вы себе представляете sum и использование при этом индекса для саммирования.
Суммирование в любом случае будет использовать natural.
Хотя при этом в объединении таблиц, условиях natural не должно быть.
Здесь тормоза в этих 7 и 30 секунд идут как раз от sum и никуда от них не денешься!
Romkin (2001-12-27 13:21:00) [18]Скорее всего условия, плюс суммирование довольно медленная операция, может IB пытается перестроить запрос по-другому.. мало ли что
по виду это отчет, поэтому рекомендую делать SP с последовательной выборкой, а также проверить планы запросов (всех), надо избегать NATURAL по большим таблицам (а для join часто так..) а также использование одновременно двух и более индексов...
Мне помню, приходилось в процедуре переворачивать запросы вверх ногами, чтобы natural шел по малой таблице
Подобные запросы - характерное время до 10 сек на PIII, с SP по таблице ~500000 записей
VL (2001-12-27 13:13:00) [19]т.е. ты хочешь сказать, что join тормозит вычисления и выборки.
алиасы я не писал, т.к. названия полей по выборке не пересекаются и в этом случае они нужны только для удобства програмирования.
И еще один вопрос: join-ы есть в обоих вариантах
select * from .... left join .... left join ....
и
select sum(..) from .... left join .... left join ....
но первый считается 7 сек а второй 30 сек - эта разница исходит от того, что в первом случае мне выдается часть данных, а во втором - он должен для себя получить полный обьем?
Romkin (2001-12-27 12:56:00) [20]Примерно так... точно не скажу, но идея понятна
create procedure Gruop_sum (p0 integer, p1 integer)
returns (otinlnwarecode integer, Summa numeric(15,2), Summa2 ...)
as
declare variable invoice_UID integer;
declare variable FirmID integer;
begin
for select UID, otinfirmcode, otinlnwarecode from outinvoicereestr /* для всех реестров с условием... */
where ...
into :invoice_UID, :FirmID, :otinlnwarecode
do begin
Summa = 0;
Summa2 = 0;
if (/* проверка фирмы */) then
for select ... /* по накладным реестра */
where ...
into ...
do begin
/* вызов конвертации - если не select*/
execute procedure convertmoney(:otinlnprice,:otincrnccode,1,:otindate)
returning_values :...
summa = summa + resultvalue*otinlncount*(1-otindiscount/100)*1.2);
summa2 = summa2 + otinlncount;
...
end;
if (summa <> 0 or summa2 <> 0) then
suspend;
end
end