![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Тормозит FireBird [D7, firebird]
Denkop © (2003-09-30 14:01:00)
Юзаю firebird WI-V1.0.3.972, версия 3-х недельной давности.
Делаю примерно такой запрос:
SELECT * FROM MAINTABLE T1
LEFT JOIN ORG_GROUP T2 ON T1.ID_GROUP=T2.ID
LEFT JOIN REG_GROUP T3 ON T1.ID_REG=T3.ID
LEFT JOIN TOWN_GROUP T4 ON T1.ID_TOWN=T4.ID
Поля X.NAME, X.ID все проиндексированы (ID-первич,NAME-вторич);
Для доступа использую стандартные компоненты с вкладки InterBase (IBDataBase,IBTransaction,IBQuery).
Структура MAINTABLE (примерно 100000 записей):
CREATE TABLE MAINTABLE (
ID INTEGER NOT NULL,
ID_GROUP INTEGER,
NAME VARCHAR(150),
TEL VARCHAR(20),
FAX VARCHAR(20),
FIO VARCHAR(150),
EMAIL VARCHAR(240),
WEB VARCHAR(240),
ADDRESS VARCHAR(240),
ID_REG INTEGER,
ID_TOWN INTEGER,
ZIP VARCHAR(10)
);
остальные таблицы классификаторы (ID, NAME)
На машине Authlon 1400/256mb/40HDD Seagate 7200 Ata100 этот запрос выполняется около минуты!
В настройках FIB:
Database Cash: 2048
Map size: 50698
Как можно повысить быстродействие выборки?
Denkop (2003-09-30 15:48:00) [1]
Усё, я понатыкал fetchall везде где можно.
Нехорошая привычка возникла после того как я пытался почитать незафетченные данные, я тогда чуть голову не свернул себе и всем окружающим.
Всем спасибо, вопрос снят, опять глупость...
Vlad (2003-09-30 15:37:00) [2]
>Denkop © (30.09.03 15:14) [18]
Кстати, если не делать FetchAll,в грид загружаются не все выбранные записи, а только видимые. А затем, по мере скроллинга подгужаются с сервера.
Vlad (2003-09-30 15:27:00) [3]
>((UPPER(T1.NAME COLLATE PXW_CYRL) LIKE "%чёто%")
Вот тут происходит тормоз.
like( %чёто%) будет замедлять выборку
Deniz (2003-09-30 15:20:00) [4]
>Denkop ©
Специально создал тест 100 000 записей твоей структуры наполнил в IBExpert -> Test data generation
select * from TestTable
IBQuery1.Open;
~ 0.4 s
---
IBDatabase1.Open;
IBQuery1.Open;
~0.9 s
---
IBQuery1.FetchAll;
~32 s
---
Машина P-II 400 RAM 384, FB 1.0.2.908, IBX 7.08
Denkop (2003-09-30 15:14:00) [5]
Nikolay M. >> как я понял все тормоза именно с выборкой where, а чтобы это дело ускорить в памяти нужно держать и MAINTABLE.
Про fetchall: я собственноручно прописал
procedure TDataModule1.MainTableAfterOpen(DataSet: TDataSet);
begin
DataModule1.MainTable.FetchAll;
end;
Эту глупость я убрал, но
даже без этого куска в грид загружаются все выбранные записи
Vlad > Получается так...
Выбираю так:
SELECT * FROM MAINTABLE T1
LEFT JOIN ORG_GROUP T2 ON T1.ID_GROUP=T2.ID
LEFT JOIN REG_GROUP T3 ON T1.ID_REG=T3.ID
LEFT JOIN TOWN_GROUP T4 ON T1.ID_TOWN=T4.ID
WHERE T1.ID_REG=121
ORDER BY T3.NAME, T4.NAME, T2.NAME, T1.NAME
Раза полтора быстрее, а в грид загружаются все выбранные 40000 записей...
З.Ы.
сори, в посте Denkop © (30.09.03 14:01)неточность
запрос выглядит так:
SELECT * FROM MAINTABLE T1
LEFT JOIN ORG_GROUP T2 ON T1.ID_GROUP=T2.ID
LEFT JOIN REG_GROUP T3 ON T1.ID_REG=T3.ID
LEFT JOIN TOWN_GROUP T4 ON T1.ID_TOWN=T4.ID
WHERE ((UPPER(T1.NAME COLLATE PXW_CYRL) LIKE "%чёто%")
AND (T1.ID_REG=121)
ORDER BY T3.NAME, T4.NAME, T2.NAME, T1.NAME
Карелин Артем (2003-09-30 15:01:00) [6]
Denkop © (30.09.03 14:33) [9]
Завтра после обеда стукни ко мне в аську, я как раз возьму свою базу. По руками примера нет, сочинять неохота.
Хотя дело видимо в другом. Я тоже склоняюсь к FetchAll. Ну или в перемещении в конец набора данных.
Vlad (2003-09-30 14:46:00) [7]
>Alexandr © (30.09.03 14:41) [12]
По вашему, размер грида у автора вмещает 100 тыс. видимых записей ?
Судя по времени выполнения запроса, приведенному автором, происходит именно FetchAll, а уж почему так происходит - автору виднее.
Alexandr (2003-09-30 14:44:00) [8]
обсуждение плавно переходит в маразм...
сорри, не удержался.
Nikolay M. (2003-09-30 14:44:00) [9]
> Denkop © (30.09.03 14:25) [6]
> Вся беда в том, что все вместе взятые справочники содержат
> не более 1000 записей,
В вышеприведенном примере в запросе используются 3 справочника, в каждом 2 поля: ID, Name. Допустим, ка каждую запись примерно приходится по 200 байт => справочник занимает 200КБ, 3 справочника: 600КБ, пусть будет мегабайт: имхо, с 256 МБ можно позволить себе такую роскошь...
Да, еще в догонку: а тебе действительно нужно получать все 100 000 записей на клиенте? В SQL FB есть что-то вроде TOP, LIMIT или подобного для ограничения возвращаемого кол-ва строк?
Карелин Артем (2003-09-30 14:43:00) [10]
Vlad © (30.09.03 14:39)
Ну это... При вызове Next/Last и фетчатся записи. А напрямую по-моему облом.
Alexandr (2003-09-30 14:41:00) [11]
мера необходимости определяется программистом, который управляет размером грида, в первую очередь.
А уж грид возмет сколько ему надо, а IBQuery отдаст сколько попросят.
Vlad (2003-09-30 14:39:00) [12]
>Карелин Артем © (30.09.03 14:34) [10]
Возможно, только вот я что-то не нашел как в IBQuery этим делом управлять можно. Хотя бы курсор установить сервер/клиент. Такое впечатление что он фетчит записи так как сам захочет. И неясно чем определяется эта "мера необходимости"
Карелин Артем (2003-09-30 14:34:00) [13]
А разве в TIbQuery сразу идет загрузка всех записей? Там читается по мере необходимости, если конечно FetchAll не вызывать. Если мне не изменяет память :)
Denkop (2003-09-30 14:33:00) [14]
Карелин Артем > поясни пож
Alexandr> ....
Vlad (2003-09-30 14:27:00) [15]
Denkop © (30.09.03 14:25) [6]
Выход из положения м.б. следующий. Отказаться от Query и пользоваться IBDataSet. Там, если мне не изменяет память можно устанавливать BufferChunks, т.е. будут подргужаться не все сразу записи.
Карелин Артем (2003-09-30 14:25:00) [16]
Лично я пользуюсь вложенными циклами For select в хранимых процедурах. Летает со свистом при нормальных индексах. Фетчинг идет сразу или фетчится по мере надобности? Если первое, то почти нормально. Если второе - дело пахнет керосином.
Denkop (2003-09-30 14:25:00) [17]
Nikolay M.>>
Вся беда в том, что все вместе взятые справочники содержат не более 1000 записей, а держать в памяти 100000 записей на 256Mb наврядли получится. Даже если это получится, то всё это дело со временем сгрузится в подкачку, т.к. на машине стоит куча софта, которым юзверь не прочь попользоваться.
пробовал и через лукапы связывать, толку нет... таже картина
Vlad >>
А какой выход с положения, может есть смысл перейти на другую СУБД? Ведь это справочник и лично меня бы очень сильно разозлил факт выборки длительностью в минуту!!
Mike Kouzmine (2003-09-30 14:25:00) [18]
Alexandr © (30.09.03 14:20) [3] Ваша правда.
Johnmen (2003-09-30 14:22:00) [19]
1. Может у тебя справочники очень большие.
2. LEFT JOIN очень долгая операция
3. М.б. надо все-таки JOIN ? Он очень быстр к тому же...
Alexandr (2003-09-30 14:20:00) [20]
план. нужен план.