Sql Delphi-查询运行缓慢
我的查询,当运行时需要大约7秒来完成应该做的事情。但是,由于它插入了大约30条记录,我认为它太慢了。现在,要么我运行的查询写得不好,要么它确实需要这么多时间。但那会很奇怪。底层数据库是SQLite,查询如下所示:Sql Delphi-查询运行缓慢,sql,sqlite,delphi,delphi-xe4,unidac,Sql,Sqlite,Delphi,Delphi Xe4,Unidac,我的查询,当运行时需要大约7秒来完成应该做的事情。但是,由于它插入了大约30条记录,我认为它太慢了。现在,要么我运行的查询写得不好,要么它确实需要这么多时间。但那会很奇怪。底层数据库是SQLite,查询如下所示: procedure TForm1.cxButton1Click(Sender: TObject); begin with UNIquery2 do begin Close; SQL.Clear; UNIQuery1.First; while Uniquery1.EOF = fa
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”为布尔值(真/假)外,所有字段均为文本
答案已修改(根据LS_dev的建议):
如果SQL插入本身很慢,我建议首先在交互式客户机中测试其执行速度。或者编写一个简单的测试应用程序,执行一次硬编码插入并测量其执行时间
此外,您还可以使用调试器、日志记录或探查器查找代码中耗费时间的操作-可以是
Uniquery1。例如,Next
或ExecSQL
。不了解Delphi,但会提出一些改进建议:
commit
命令SQL.Text:=…
可能已过期。如果此属性集编译SQL语句,则将其移出while将防止不必要的VDBE编译INSERT-INTO-MYTABLE)从源表中选择:a1、FIELD2、FIEDL3、FIELD4,设置ParamByName('a1')。asString:=AdvOfficeStatusBar1.Panels[0]。Text
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;
建议使用改进的DB处理:
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;
您应该在UniQuery1循环之外为UniQuery2分配一次SQL语句。还要定义参数(ptInput和ftString/ftString),然后可能准备查询(如果UniQuery有,则不知道)。然后,在循环中,您只需设置参数值。此外,当使用代码提问时,您需要提供变量定义。这种独一无二的动物是什么?编辑您的问题。作为第一步,停止在循环中使用
XXXByName
,而是使用索引。我需要查看所有UNIQuery1记录。我不确定我是否在跟踪您。你能给我一些你认为应该如何的代码吗;这是一个很好的例子。
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;