powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Медленное получение данных через TFDQuery (FireDAC)
25 сообщений из 59, страница 1 из 3
Медленное получение данных через TFDQuery (FireDAC)
    #39122099
Трость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброе утро.

СУБД MSSQL2008R2
Не могу разобраться, почему выполнение запроса через SSMS выполняется быстро (8 сек.) через FireDAC очень медленно. Строк примерно 140т.

Я понимаю, что выполнение через SSMS и через приложение не одно и тоже. Но запрос элементарный без join и т.п.

Возможно дело в каких либо настройках TFDConnection или TFDQuery?
А возможно это непоправимо т.к. TFDQuery получает данные медленно (буферизация медленная или ещё что...).

Подскажите что можно посмотреть?
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122134
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Трость,

На ФаирДАК особо ничего не делал, но предполагаю что:
1. У ФаирДАК такая-же болезнь как и TClientDataSet. Я об этом писал тут . При вызове, который возвращает большое количество информации он будет делать что-то никому не понятное и что-то очень долгое. Торможение равно квадрату возвращённой информации.
2. Наверняка некие "умельцы" тебе сейчас скажут, что возвращать на клиента 150 тыс строк - это не правильно. И то, что ФаирДАК работает медлено - это твоя ошибка, а не ФаирДАКа. Но я тебе такого не говорю.

Ну может к ФаирДАК это и не относится, и там действительно надо какому-то свойство присвоить Значение:=True; А так, это всё основано на очень негативном опыте от TClientDataSet.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122137
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Трость,

Попробуй в новом тестовом проекте сделать тот-же самый запрос через ADO - я уверен, что он пройдёт как и в SMSS за 8 секунд.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122157
Трость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Valery_BТрость,

Попробуй в новом тестовом проекте сделать тот-же самый запрос через ADO - я уверен, что он пройдёт как и в SMSS за 8 секунд.

Хм... странно... TADOQuery работает быстро, даже немного быстрее чем через SSMS.
Много отзывов читал про FireDAC, вроде писали что быстрее и т.п. получается при чтении большого количества строк работает медленно 140т. читает 32 сек. а ADO справляется за 8...

Хотелось бы услышать ещё мнения.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122178
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тростьпри чтении большого количества строк работает медленно 140т. читает 32 сек. а ADO справляется за 8...

Ну 32 секунды вместо 8 - это ещё терпимо. Это "всего-то" в 4 раза медленнее, чем должно. В случае КлиентскогоДатаСета это было бы 3.2 минуты против 8 секунд АДО)

Что за ЦП ? У меня "Коре Йа7" - замена на ещё более быстрый повысит скорость, это 100%:))
Посмотри на загрузку 1 ядра ЦП во время получения данных - он загружен на 100%

Тебе помогут только разработчики ФаирДАК. Но я думаю, что они тебе скажут смотреть п.2 моего ответа )
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122180
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, скорее всего "Тормознутость" - не от количества строк, а от объёма данных.
Если вернуть миллион строк только с одним полем типа Integer, то они засосуться пропорционально быстрее, чем 100тыс но с 10 разными полями.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122189
bk0010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне на Informix помогло отключение fiMeta в FetchOptions и ReadOnly=true - скорость выросла многократно.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122194
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valery_Bскорее всего "Тормознутость" - не от количества строк, а от объёма данныхне без этого конечно. как там датасеты/провайдеры формируют датапакет и сколько реаллокаций при этом делают можно предполагать зря что ли я свой мидас/cds переучивал
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122214
Трость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
bk0010Мне на Informix помогло отключение fiMeta в FetchOptions и ReadOnly=true - скорость выросла многократно.

Действительно лучше, вместо 32 сек стало 26... но это далеко от идеала...
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122229
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vavan, учить умершую технологию Midas помоему извращение в 2015)

Что бы абстрагироваться от получения данных раньше я использовал абстрактный класс - TxClientDataSet;
Но теперь, для доступа к данным у меня используется интерфейс IDataSet с 2-3 базовыми свойствами. Что бы не реализовывать кучу свойств в интерфейсе создан под-класс для IDataSet - TDataSetProperties. Фактически, это просто класс с набором строковых свойств.

Таким образом в TDataSet, возвращаются данные полученные вообще не понятно каким способом.
Это гарантирует работу с любой БД.

Вот что получилось:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
TDataSetProperties = class
 private
    FDBName: String;
    FProviderName: String;
    FParams: TParams;
 Public
    Property DBName:String read FDBName write FDBName;
    Property ProviderName: string read FProviderName write FProviderName;
    Property Params: TParams read FParams write FParams;
    Constructor Create;
    Destructor Destroy; Override;
end;


IDataSet = Interface
 ['{A05A188A-F45D-43D0-A410-D8EF6631DBBC}']
  Function Identity : Integer;
  Procedure ApplyUpdates(MaxErrors:Integer);
  Procedure SetParameter(ParamName:String; Value:OLEVariant);
  Procedure OpenOrExecute;
  Procedure OpenOrExecuteAsync(OnTerminate:TDataSetNotifyEvent);
  Procedure CancelAsyncExecution(OnTerminate:TDataSetNotifyEvent);

  Property ProviderName: string read GetProviderName write SetProviderName;
  Property Properties : TDataSetProperties read GetDataSetProperties;
end;

...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122241
Трость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уж очень интересно, что на это скажет Dmitry Arefiev. По возможности просим ответить...
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122247
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ой, главное свойство не скопировалось :)
Код: pascal
1.
2.
3.
IDataSet = Interface
 ['{A05A188A-F45D-43D0-A410-D8EF6631DBBC}']
 Function DataSet:TDataSet;



А используется так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
Procedure TForm1.Button1Click(Sender:TObject);
var
 D:IDataSet;
begin
 D:=TDefaultDataSet.Create(Nil);
 D.ProviderName:='Select * from Table1';
 D.OpenOrExecute;
 ShowMessage(D.DataSet.Fields[0].AsString);
end;


В случае с интерфейсами делать D.Free не надо.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122263
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы там Fetch всех записей делаете? Или не всех? Время очень разное.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122270
Трость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Michael LongneckВы там Fetch всех записей делаете? Или не всех? Время очень разное.

Mode = fmAll

Хотя если Mode = fmOnDemand и делаем Query.Last, то скорость можно сказать не отличается
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122288
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну так логично, что сделав Query.Last скорость не будет отличаться. Но SSMS не делает Last.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122294
Трость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Michael LongneckНу так логично, что сделав Query.Last скорость не будет отличаться. Но SSMS не делает Last.

Так, и к чему вы клоните? Как можно ещё попробовать?
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122302
Glays
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тростьи делаем Query.Last
А в SSMS тоже все строки выгружаем?

Вообще, пока я бы сказал что Valery_Bвозвращать на клиента 150 тыс строк - это не правильно.
Потому что 150 тысяч строк не подразумевают под собой взаимодействие с человеком, а скорее всего будут обработаны или экспортированы(скорее всего в эксель), а это чаще всего имеет смысл делать силами самого сервера.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122303
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ни к чему. Только к тому, что SSMS фетчит первые N записей и останавливается. Точно также как и FireDac в режиме OnDemand. Таким образом "тормоза" это просто разница между частичным и полным fetch.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122305
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что касается 150 тыс, то если обработка не подразумевает возвратов назад, то надо включить Unidirectional и гнать цикл до конца датасета. И быстрее и памяти много не надо.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122310
igor888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Michael Longneck,

Я так и не могу понять, какая разница в Mode в плане чтения 140т. строк.

Вы хотите сказать, что если читать пакетно то скорость увеличится?

--Что касается 150 тыс, то если обработка не подразумевает возвратов назад, то надо включить Unidirectional

В том то и дело, что это ограничения на ровном месте, когда TADOQuery работает не хуже SSMS
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122319
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я хочу сказать, что если выполнить запрос, зафетчить первые 200 записей и остановиться (как делает SSMS), это быстрее чем не останавливаться и вычитать из сервера все 140 тыс. Вы понимаете что запрос грубо делится на собственно исполнение и чтение данных? И вторая операция может быть сделана по частям?
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122326
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GlaysПотому что 150 тысяч строк не подразумевают под собой

Ну я сразу так и сказал, наверняка тут будут говорить о не правильности запроса и т.п. :)

В моём случае, а возвращаю координаты всех звёзд, комет и астеройдов в Тентуре (это направо от Большой Медведицы) и прокладываю маршрут своего Пепелаца так, что бы он врезался в эти объекты.
т.е. обсуждение нужно мне 150 тыс строк или нет - это отдельная тема.


Автору темы:
Сделай:
Код: pascal
1.
2.
ADODataSet.First;
While not ADODataSet.Eof do ADODataSet.Next;


Код: pascal
1.
2.
FireDacDataSet.First;
While not FireDacDataSet.Eof do FireDacDataSet.Next;


Разница будет минимальна. ADO(и SSMS) по умолчанию получает все записи сразу без Fetchа и ему подобных.
Хотя сам цикл While not EOF у АДО медленней, чем у ClientDataSet.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122328
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Michael Longneck
(как делает SSMS)

Только SSMS так не делает.
Если показано, что "Запрос выполнен" - то запрос выполнен полностью.
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122397
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, действительно, фетч продолжается в фоне. Однако первые видимые записи он показывает гораздо раньше окончания фетча. Вы на какое время ориентируетесь - на то, что пишет SSMS в строке статуса как время выполения? И что, оно гораздо меньше времени запроса через FireDac при fmAll?
...
Рейтинг: 0 / 0
Медленное получение данных через TFDQuery (FireDAC)
    #39122398
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valery_Bучить умершую технологию Midas помоему извращение в 2015я начал ее юзать где-то в 98-99-м и когда проблемы утомили совсем году в 2005-6-м пересел на hyperbase и собственный транспорт, так что дело было уже лет десять как. да возможно и сейчас бы предпочел переучивать хоть что-то готовое чем лепить полностью с нуля. а совсем умрет она не раньше дельфей и проектов на ней построенных
...
Рейтинг: 0 / 0
25 сообщений из 59, страница 1 из 3
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Медленное получение данных через TFDQuery (FireDAC)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]