Прекъсване на SQL заявка с ограничение на времето за обработка

Мога ли да пиша SQL заявки с помощта на DELPHI, dbgo DB компоненти и сървър на база данни на SQL Server, които са ограничени по отношение на времето за обработка?

като

select * from table where ......  

и process_time_limit = 5 sec ?

По-добре да ми дадете 10% от редовете в рамките на определен срок, вместо да чакам с часове за пълния набор от данни на заявката


person Franz    schedule 03.02.2013    source източник
comment
Какво искате да се случи, когато изтекат 5 секунди? Изключение, с което можете да се справите, или нещо друго? И какво издание използвате (може би Resource Governor може да помогне тук).   -  person Aaron Bertrand    schedule 03.02.2013
comment
Вижте също stackoverflow.com/questions/5077051/ - CommandTimeout може да помогне, но може да зависи от няколко други фактора.   -  person Aaron Bertrand    schedule 03.02.2013
comment
Може би трябва да избягвате започване на заявки, които отнемат часове за изпълнение.   -  person Ondrej Kelle    schedule 03.02.2013
comment
@TOndrej: понякога просто се нуждаеш от тази информация :-)   -  person Marjan Venema    schedule 04.02.2013
comment
@MarjanVenema В такива случаи трябва да е възможно да се оптимизира базата данни, така че заявките да не отнемат толкова време.   -  person Ondrej Kelle    schedule 04.02.2013
comment
@TOndrej: Да, не оспорвам мнението ви. Въпреки това, когато трябва да преминете през 200 или дори 20 GB данни, за да получите информацията, от която се нуждаете, това просто ще отнеме време, независимо колко оптимизирана е вашата база данни и/или заявка. Може би бихте могли да разделите заявката на по-малки, но множество заявки с временни резултати може просто да скрият (и да увеличат) общото време, необходимо за получаване на отговора.   -  person Marjan Venema    schedule 04.02.2013


Отговори (1)


ADO компоненти:

Бих опитал асинхронното извличане на данни. Когато изпълните заявката, ще запомните кога сте започнали и всеки път, когато OnFetchProgress събитие се задейства, ще проверите дали EventStatus все още е в състояние esOK и проверете времето, изтекло от изпълнението на заявката. Ако е изтекъл, можете да отмените извличането на данни, като използвате Cancel метод на вашия набор от данни.

Исках да използвам нещо като следния (нетестван) псевдокод:

var
  FQueryStart: DWORD;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // configure the asynchronous data fetch for dataset
  ADOQuery1.ExecuteOptions := [eoAsyncExecute, eoAsyncFetchNonBlocking];
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // store the query execution starting time and execute a query
  FQueryStart := GetTickCount;
  ADOQuery1.SQL.Text := 'SELECT * FROM Table';
  ADOQuery1.Open;
end;

procedure TForm1.ADOQuery1FetchProgress(DataSet: TCustomADODataSet; Progress,
  MaxProgress: Integer; var EventStatus: TEventStatus);
begin
  // if the fetch progress is in esOK (adStatusOK) status and the time since
  // the query has been executed (5000 ms) elapsed, cancel the query
  if (EventStatus = esOK) and (GetTickCount - FQueryStart >= 5000) then
    DataSet.Cancel;
end;
person TLama    schedule 03.02.2013
comment
Хм, документът за Cancel казва: Отменя модификациите на активния запис, ако тези промени все още не са публикувани. Сигурни ли сте, че ще работи за предвидената цел тук - да отмените следващото извличане? - person ain; 03.02.2013
comment
Благодаря за тази споделена идея, ще се опитам да я направя - person Franz; 04.02.2013