Delphi-查询运行缓慢



我的查询,当运行时需要大约7秒才能完成应该做的事情。但是,由于它插入了大约30条记录,我认为它太慢了。现在,要么我运行的查询写得不好,要么它确实花了这么多时间。但这会很奇怪。底层数据库是SQLite,查询如下:

procedure TForm1.cxButton1Click(Sender: TObject);
begin
with UNIquery2 do begin
  Close;
  SQL.Clear;
UNIQuery1.First;
while Uniquery1.EOF = false do begin
SQL.Text:= 'INSERT INTO MYTABLE (FIELD1,FIELD2,FIELD3,FIELD4) VALUES (:a1,:a2,:a3,:a4)';
         ParamByName('a1').asString := AdvOfficeStatusBar1.Panels[0].Text;
         ParamByName('a2').asString := UniTable1.FieldByName('FIELD2').asString;
         ParamByName('a3').asString := Uniquery1.FieldByName(',FIELD3').asString;
         ParamByName('a4').Value := Uniquery1.FieldByName('FIELD4').Value;//boolean field true/false
         Uniquery1.Next;
         ExecSQL;
end;
end;
end;

那么,有人能告诉我这是否可以,或者我错过了什么吗?所有字段都是文本,但"a4"是布尔值(true/false)。

答案,修改(基于LS_dev的建议):

procedure TForm1.cxButton1Click(Sender: TObject);
begin
    with UNIquery2 do begin
        Close;
        SQL.Clear;
        SQL.Add('INSERT INTO MYTABLE (FIELD1,FIELD2,FIELD3,FIELD4) VALUES (:a1,:a2,:a3,:a4)');
        SQL.Prepare;
        UniTransaction.AddConnection(UniConnection2);
        UniTransaction.StartTransaction;
try
        UNIQuery1.First;
        while Uniquery1.EOF = false do begin
            Params[0].asString := AdvOfficeStatusBar1.Panels[0].Text;
            Params[1].asString := UniTable1.FieldByName('FIELD2').asString;
            Params[2].asString := Uniquery1.FieldByName(',FIELD3').asString;
            Params[3].Value := Uniquery1.FieldByName('FIELD4').Value;//boolean field true/false
            Uniquery1.Next;
            ExecSQL;
        end;
        UniTransaction.Commit;
finally
  if UNIquery2.Connection.InTransaction then
    UNIquery2.Connection.Rollback;
    end;
    end;
    end;

不了解Delphi,但会建议一些改进:

  1. 您没有使用交易。您应该禁用自动提交之类的功能,并在所有插入后使用COMMIT命令;

  2. 你的SQL.Text:=...可能已经过时了。如果此属性集编译SQL语句,将其置于while之外将防止不必要的VDBE编译;

  3. 如果您的意图是将行从一个表复制到另一个表(使用静态字段),则可以使用单个SQL命令(如INSERT INTO MYTABLE SELECT :a1, FIELD2, FIEDL3, FIELD4 FROM source_table)来设置ParamByName('a1').asString := AdvOfficeStatusBar1.Panels[0].Text

这是通用数据库使用率的改进,希望能给你一些指导。

建议使用唯一SQL:

procedure TForm1.cxButton1Click(Sender: TObject);
begin
    with UNIquery2 do
    begin
        SQL.Clear;
        SQL.Add('INSERT INTO MYTABLE (FIELD1,FIELD2,FIELD3,FIELD4) SELECT ?,FIELD2,FIELD3,FIELD4 FROM UNIquery1_source_table');
        Params[0].asString := AdvOfficeStatusBar1.Panels[0].Text;
        ExecSQL;
    end;
end;

建议使用改进的数据库处理:

procedure TForm1.cxButton1Click(Sender: TObject);
begin
    with UNIquery2 do 
    begin
        Close;
        SQL.Clear;
        SQL.Add('INSERT INTO MYTABLE (FIELD1,FIELD2,FIELD3,FIELD4) VALUES (:a1,:a2,:a3,:a4)');
        SQL.Prepare;
        UniTransaction.AddConnection(UniConnection2);
        UniTransaction.StartTransaction;
        UNIQuery1.First;
        while Uniquery1.EOF = false do 
        begin
            Params[0].asString := AdvOfficeStatusBar1.Panels[0].Text;
            Params[1].asString := UniTable1.FieldByName('FIELD2').asString;
            Params[2].asString := Uniquery1.FieldByName(',FIELD3').asString;
            Params[3].Value := Uniquery1.FieldByName('FIELD4').Value;//boolean field true/false
            Uniquery1.Next;
            ExecSQL;
        end;
        UniTransaction.Commit;
    end;
end;

如果SQL INSERT本身很慢,我建议先在交互式客户端中测试它的执行速度。或者编写一个简单的测试应用程序,执行一个硬编码的INSERT并测量其执行时间。

此外,您还可以使用调试器、日志记录或探查器来找出代码中消耗时间的操作——例如,可以是Uniquery1.NextExecSQL

相关内容

  • 没有找到相关文章

最新更新