Запросов MySQL из внешнего приложения


У меня есть база данных, мне нужно, чтобы запрос снова и снова как можно быстрее. Мои запросы довольно быстро выполнить, но там, кажется, некоторая дополнительная задержка. У меня ощущение, что это отставание связано с тем, что я возбуждения и де-возбуждения подключения каждый раз. Есть ли способ избежать этого?

Я не использую libmysql (по крайней мере, не напрямую). Я использую "пакет mysql50" в Lazarus/FreePascal (аналог Дельфи), который в свою очередь использует libmysql (я думаю).

Цель этой библиотеки-передать запрос, отправленный из MQL4 (умилостивительную Си-подобного языка для рынка финансовой биржи), и возвращает одну строку из моей базы данных MySQL (к которому он подключается через трубу).

Я был бы очень признателен, если кто-то взял посмотреть мой код и указать (или даже фиксированный) некоторые недостатки.

{$CALLING STDCALL}

library D1Query;

{$mode objfpc}{$H+}

uses
  cmem,
  Windows,
  SysUtils,
  profs_win32exceptiontrap,
  mysql50;

var

  sock: PMYSQL;
  qmysql: st_mysql;

type
  VArray = array[0..100] of Double;
  PArray = ^VArray;


  procedure InitSQL; stdcall;
  begin

    mysql_init(PMySQL(@qmysql));
    sock :=
      mysql_real_connect(PMysql(@qmysql), '.', 'root', 'password', 'data', 3306, 'mysql', CLIENT_MULTI_STATEMENTS);
    if sock = nil then
    begin
      OutputDebugString(PChar('  Couldn''t connect to MySQL.'));
      OutputDebugString(PChar(mysql_error(@qmysql)));
      halt(1);
    end;

  end;

  procedure DeInitSQL; stdcall;
  begin

    mysql_close(sock);
  end;

  function SQL_Query(QRY: PChar; output: PArray): integer; stdcall;
  var
    rowbuf: MYSQL_ROW;
    recbuf: PMYSQL_RES;
    i: integer;
    nfields: LongWord;


  begin
    InitSQL();

    if (mysql_query(sock, QRY) < 0) then
    begin
      OutputDebugString(PChar('  Query failed '));
      OutputDebugString(PChar('   ' + mysql_error(sock)));
    end;

    recbuf := mysql_store_result(sock);
    nfields :=  mysql_num_fields(recbuf);
    rowbuf := mysql_fetch_row(recbuf);


    if (rowbuf <> nil) then
    begin
      for i:=0 to nfields-1 do
          output^[i] := StrToFloatDef(rowbuf[i], -666);
    end;

    mysql_free_result(recbuf);
    DeInitSQL();
    Result := i;


  end;

exports
  SQL_Query,
  InitSQL,
  DeInitSQL;

begin
end.


887
6
задан 25 мая 2011 в 12:05 Источник Поделиться
Комментарии
2 ответа

Самое главное здесь, чтобы не создавать и разрушать связи в рамках выполнения вашего запроса. Силу вызывающий код, чтобы создать подключение (или создать его самостоятельно, если его не обошлось), но не уничтожить до тех пор, пока библиотека будет выгружена. Это должно улучшить скорость.

3
ответ дан 28 августа 2011 в 08:08 Источник Поделиться

Поскольку вы звоните InitSQL() и DeInitSQL() внутри функции SQL_QUERY, каждый раз, когда вы называете SQL_QUERY вы на самом деле создать соединение и уничтожить его. В этом случае издержки ввода-вывода в базе данных. Добавить еще один параметр в SQL_QUERY isLastStmt и отправить, правда с последним утверждением уничтожить
если isLAstStmt тогда DeInitSQL();

Также добавим, если носок = шь тогда просто после строки mysql_init(PMySQL(@qmysql));
в InitSQL() процедуры. Таким образом, если носок равна нулю, соединение будет сделано. И учитывая, что первый шаг я уже упоминал о уничтожить операция, соединение будет закрыто после выполнения последней инструкции.

1
ответ дан 25 апреля 2013 в 07:04 Источник Поделиться