我的查询,运行大约需要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;
答案 0 :(得分:8)
不知道Delphi,但会提出一些改进建议:
您没有使用交易。在所有插入后,您应该执行类似自动提交禁用和COMMIT
命令之类的操作;
你的SQL.Text:=...
应该不合时宜。如果此属性集编译SQL语句,则将其置于while之外将防止不必要的VDBE编译;
如果您的意图是将行从一个表复制到另一个表(使用静态字段),您可以使用INSERT INTO MYTABLE SELECT :a1, FIELD2, FIEDL3, FIELD4 FROM source_table
之类的单个SQL命令,设置ParamByName('a1').asString := AdvOfficeStatusBar1.Panels[0].Text
这是通用的DB使用改进,希望给你一些指导。
使用唯一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;
答案 1 :(得分:0)
如果SQL INSERT本身很慢,我建议首先在交互式客户端中测试其执行速度。或者编写一个简单的测试应用程序,它执行一个硬编码的INSERT并测量其执行时间。
此外,您可以使用调试器,日志记录或分析器来查找代码中消耗时间的操作 - 例如Uniquery1.Next
或ExecSQL
。