Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Delphi-查询运行缓慢_Sql_Sqlite_Delphi_Delphi Xe4_Unidac - Fatal编程技术网

Sql Delphi-查询运行缓慢

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

我的查询,当运行时需要大约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”为布尔值(真/假)外,所有字段均为文本

答案已修改(根据LS_dev的建议):


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


此外,您还可以使用调试器、日志记录或探查器查找代码中耗费时间的操作-可以是
Uniquery1。例如,Next
ExecSQL

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

  • 您没有使用事务。您应该在所有插入之后禁用自动提交和
    commit
    命令

  • 您的
    SQL.Text:=…
    可能已过期。如果此属性集编译SQL语句,则将其移出while将防止不必要的VDBE编译

  • 如果您的目的是将行从一个表复制到另一个表(使用静态字段),则可以使用单个SQL命令(如
    INSERT-INTO-MYTABLE)从源表中选择:a1、FIELD2、FIEDL3、FIELD4,设置
    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;
    
    建议使用改进的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;