代码之家  ›  专栏  ›  技术社区  ›  cja

为什么SQLYG返回MySQL查询结果的速度比我的Delphi程序快10倍?

  •  2
  • cja  · 技术社区  · 17 年前
    select rectype,jobid,jobrecid,template,assignedto,entereddt,enteredby,ref1,processed,processeddt,
    processbydt,title,description,connectlanhandle,finished,updateddt,ref2,cancelled,
    requireaccept,acceptrejectstate,acceptrejectbydt,alert1dt,alert2dt,alert3dt,despatchallowed,
    flag,ref3,projectid,duration,skillset,postcode,prefschedulefrom,prefscheduleto,customdata1,
    customdata2,customdata3,hasnotes,displayjobtype,createdby,createddt,colour
     from jobs
     where updateddt >= '1982-02-05 17:25:38'
     or (processed = 'N' and
         cancelled = 'N')
     order by jobid, jobrecid
    

    有什么想法可以让我的程序更快吗?

    7 回复  |  直到 17 年前
        1
  •  6
  •   Jon Skeet    17 年前

        2
  •  5
  •   Mohammed Nasman    17 年前

    我在基本表(无连接)上尝试了这一自我体验,发现即使单击“全部显示”复选框,SQLyog也不会立即将所有结果显示在网格上,通过将滚动按钮移动到最低区域进行自我体验,您会注意到SQLyog会慢下来几分钟,并显示更多结果。

    MyDac from DevArt 它使用直接访问mysql(即使没有mysql客户端库)。

    最重要的是,不要试图一次向用户显示80000条记录。

    MySql GUI tools 来自使用Delphi构建的sun;-)

        3
  •  2
  •   Stephane Wierzbicki    17 年前

    我猜这是因为SQLyog使用本机MySQL C API(直接连接),而您使用的是ODBC连接器。 您是否尝试过第三方连接器,如Devart的MyDAC?您可以从那里获得一个免费试用版,并用它测试您的应用程序。

    FWIW我已经使用MyDac多年了,我非常满意(性能/奖励/支持)

        4
  •  2
  •   Tim Sullivan    17 年前

    为了解决这个性能问题,您可以使用狡猾的技巧。因为您基本上是在启动时将数据集的缓存加载到应用程序中,所以您可以对此进行线程化。加载仍然需要6到8秒,但应用程序仍然会启动,UI仍然可用。如果有人在加载缓存之前做了一些需要缓存的事情,您可以简单地显示沙漏光标,或显示一条消息“请稍候…”,直到缓存准备就绪。

    在线程中执行数据访问时需要注意的一点是,通常需要在线程中创建单独的数据库连接。大概是这样的:

    type
      TLoadCacheThread = class(TThread)
      private
        FConnection : TODBCConnection; // Or whatever, I don't use ODBC :-)
        FQuery : TODBCQuery;
        FMemData : TkbmMemTable; // This is what I use, YMMV
      protected
        procedure PopulateCachedDataset;
      public
        constructor Create; override;
        procedure Execute; override;
      end;
    
    constructor Create;
    begin
      inherited Create(True); // create suspended thread
      FConnection := TODBCConnection.Create(nil);
      // Set any properties for the connection here.
      FQuery := TODBCQuery.Create(nil);
      // Set any properties for the query here.
      FQuery.SQL.Text := 'select * from mytable';
      Resume;
    end;
    
    procedure Execute;
    begin
      FQuery.Open;
      FMemTable.LoadFromDataset(FQuery);
      Synchronize(PopulateCachedDataset);
    end;
    
    // The idea here is that you're loading into a mem dataset, which can then
    // quickly be copied to another memory dataset, rather than loading the
    // cached data directly from FQuery, which is slow and why we're threading
    // in the first place. This assumes you have some kind of globalsettings unit
    // or class, and it has a cacheddataset variable or property.
    procedure PopulateCachedDataset;
    begin
      GlobalSettings.CachedDataset.LoadFromDataset(FMemTable);
    end;
    

        5
  •  1
  •   curious slab    17 年前

    您可以在查询中使用LIMIT 01000,然后在用户到达远端时更改它-通过签入OnAfterScroll事件。

        6
  •  0
  •   Wiseman    17 年前

    在我看来,您应该仔细考虑您的应用程序和/或数据库体系结构——在处理80K记录时,这是不好的。试着缩小你的问题范围——如果你不想让你的生活更简单——没有人会这么做

        7
  •  0
  •   Harriv    17 年前

    SQLyog可能不会一次加载所有80000行,至少我使用的一些db工具在滚动时会“按需加载”。如果绝对需要一次获取所有记录,请考虑使用线程执行查询并填充内部数组。