- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下行来定位查询中的一行。
if Query.Locate('Line;Hour;Minute',VarArrayOf([Line-400,AHour,minuteof(Start)]),[]) = true then
这很慢,现在我记得可以将索引添加到查询中,这样定位本身就会快好几倍。不幸的是,我似乎找不到这个例子。
有人可以帮帮我吗?问候罗伯特
最佳答案
有趣的问题。
更新请参阅下面的更新。
我在 SS2014 Sql Server 上设置了一些测试数据,以使用如下代码运行一些测试:
ID := 1;
for Line := 1 to 1000 do begin
for AHour := 1 to 24 do begin
for AMinute := 1 to 60 do begin
AdoQuery1.InsertRecord([ID, Line, AHour, AMinute]);
Inc(ID);
end;
end;
end;
end;
然后,我运行了一些像这样的测试
procedure TForm1.LocateTest1(DisableControls, UseSort : Boolean);
var
T1 : Integer;
Line,
AHour,
AMinute : Integer;
begin
AdoQuery1.Sql.Text := 'select * from linetest order by line, ahour, aminute';
AdoQuery1.CursorLocation := clUseClient;
AdoQuery1.Open;
T1 := GettickCount;
if DisableControls then
AdoQuery1.DisableControls;
if UseSort then
AdoQuery1.Recordset.Sort := 'Line,AHour,AMinute';
Line := 1000;
AHour := 23;
for AMinute := 60 downto 1 do begin
if not AdoQuery1.Locate('Line;AHour;AMinute', VarArrayOf([Line, AHour, AMinute]), []) then
Caption := Format('Locate failed %d %d %d', [Line, AHour, AMinute]);
end;
Memo1.Lines.Add('Test1 : ' + IntToStr(GetTickCount - T1));
if DisableControls then
AdoQuery1.EnableControls;
AdoQuery1.Close;
end;
之所以涉及Disable/EnableControls是因为我报的结果这里Why does scrolling through ADOTable get slower and slower?,即使没有 db-aware,调用 DisableControls 也会对滚动速度产生巨大影响涉及控制。
但是,滚动似乎不会对在 TAdoQuery 上执行 Locate() 产生重大影响,因为调用 DisableControls 只花费了大约 1.5 秒的记录时间26 秒。显然,TAdoQuery.Locate 在处理大量行时表现不佳。
UseSort 参数的想法是看是否对后面的 RecordSet 进行排序AdoQuery 对速度有任何影响,但没有,原因是 Locate 调用TCustomAdoDataSet.LocateRecord 无论如何都使用 Sort。
您提到了添加索引。不幸的是,TAdoQuery 只支持使用服务器端索引在执行 thq SQL 查询时,未在检索的结果集中定位记录。您可以添加客户端索引到 TAdoTable,但根据与上述类似的测试,令我惊讶的是,他们做了Locate() 的速度几乎没有差异。
因此,鉴于我目前的结果,使用参数化的方法似乎可能更快SELECT 仅检索当前感兴趣的行,而不是尝试定位它在一个大的测试集中。或者,您可以通过 DatasetProvider 或 FireDAC FDMemTable 等将结果集检索到 ClientDataSer 中。Ymmv,这取决于您正在做什么...
更新 自发布我的原始答案以来,我有一些进一步的更新包括在内可能会有用。
其中一个涉及使用调用 AdoQuery 的 RecordSet 的 Find 和 Filter 方法来模仿 Locate 的方法,这种方法比重复执行 AdoQuery1.Locate 快得多(大约 15 秒)。我仍在解决这个问题,将在一两天内发布另一个更新。
另一个是简要提及执行定位时执行 FireDAC FDQuery 而不是 AdoQuery。这似乎在 9 秒内完成了与使用 AdoQuery 大约需要 25 秒的同一组定位,使用以下代码:
使用 FDQuery.Locate
procedure TForm2.LocateTest;
var
T1 : Integer;
Line,
AHour,
AMinute : Integer;
begin
FDQuery1.Sql.Text := 'select * from linetest order by line, ahour desc, aminute desc';
//FDQuery1.CursorLocation := clUseClient;
FDQuery1.CursorKind := ckForwardOnly;
FDQuery1.Open;
T1 := GettickCount;
Line := 1000;
AHour := 1;
for AMinute := 1 to 60 do begin
if not FDQuery1.Locate('Line;AHour;AMinute', VarArrayOf([Line, AHour, AMinute]), []) then
Caption := Format('Locate failed %d %d %d', [Line, AHour, AMinute]);
end;
Memo1.Lines.Add('Test1 : ' + IntToStr(GetTickCount - T1));
FDQuery1.Close;
end;
关于sql-server - ADOQuery.Locate 慢,创建索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61246225/
我不确定为什么会发生这种情况,所以我将简要解释一下情况(应该很容易理解): Form1 一个执行 sql select 语句并将其显示在通过 TDataSource 组件链接到 ADOQuery1 组
我想请您帮助我的 Delphi 项目(RAD Studio),我是 Delphi 的新手。 我正在使用:TADOConnection(带连接字符串)2x ADOQUERY(设置“连接 = TADOCo
我在 Delphi 2010 应用程序中使用异步 ADO 查询。用户可以请求取消查询,否则查询可能会因错误而失败。这是我用来取消查询的代码: if not Assigned(myADOQuery.Re
尊敬的专家们,我正在尝试过滤连接到 adoquery 的 dbgrid 中的结果,根据用户对 4 个复选框的选择,用户可以选择一个或多个字段来相应地过滤数据我有这段代码,如果用户选择两个或多个复选框,
我想将 ClientDataSet 保存到文件,然后在 AdoQuery (AdoQuery.LoadFromFile()) 中打开该文件。可能吗? 或者如何将数据集保存为 pfADTG 文件格式?
我有一个ADOQuery,它将记录插入到SQL Server 2005表中,该记录已触发将数据插入到另一个表中。我使用以下代码刷新查询并避免使用Row cannot be located for up
我在这里使用的是 Delphi 5 和 SQL Server 2000。 我使用 INSTEAD OF DELETE 触发器在可更新 View 之上创建了一个 ADOQuery。 可更新 View 主
我在快速报告中遇到问题,显示 ADO 查询中的数据不正确。我使用以下 sql.text SELECT * FROM JOB_DATA INNER JOIN CUSTOMER ON JOB_DATA.C
我有这个简单的代码来检查表中是否存在记录,但它总是返回运行时错误: Arguments are of the wrong type, are out of acceptable range, or a
我正在努力寻找执行 SQL 查询的正确过程。 基本上,我有一个文本字段,用户可以在其中输入 SQL 代码,程序将执行它。不幸的是,我不知道是否会返回数据集,因此我无法判断使用哪个函数:ADOQuery
我在 Delphi 7 和 Oracle 中使用 ADOQuery。我在将参数传递给 ADOQuery 时遇到错误。我用过以下行。请帮我找出错误。 ADOQuery.Sql.text:= 'selec
我有这个返回访问冲突的代码('sqloledb.dll' 模块中地址 74417E44 的访问冲突。读取地址 786E3552'),我无法确定问题出在哪里。我唯一的猜测是 ADOQuery 对我们可以
我正在测试一些数据库组件,例如 SDAC 等,我发现了一些有趣的东西: 当我使用 TADOQuery 执行查询并且该查询有很多 blob 字段并且我获取所有行 (fetchall) 时,我的应用程序的
我正在使用 ADO 组件连接到 MS SQL 数据库。我知道如何在 DBGrid 中显示查询结果。但是,例如,我想将结果作为字符串存储在数组中。 这是否可能,或者是否有其他方式使用查询结果? 最佳答案
好的,我有一个查询应该返回所有问题编号。我想要的是获取返回的每个问题编号并将其添加到字符串列表中。 ADOQuery1.SQL.Clear; SQLQuery := 'SELECT issue FRO
我有一个通过数据源链接到 DBGrid 的 ADOQuery。 ADOQuery 和DataSource 位于DataModule 中,并且连接采用另一种形式。 有什么方法可以让我的应用程序在查询获取
我在 ADOQuery2 中有一个查询。现在我想要一个过滤器: ADOQuery2.Filter := 'where Fname like ' + QuotedStr(Txt_Search.Tex
我正在撕扯我的头发!! 即使是像这样简单的事情: procedure MyAdoQueryTest(); const MYSQL_CONNECT_STRING='Driver={MySQL OD
我有一个 Delphi 7 项目,它使用 MySQL 中的数据库来存储一些配置。每当我更改配置时,都会启用“保存”按钮。此按钮中的 OnClick 过程调用 TADOQuery.Edit、Select
我有以下行来定位查询中的一行。 if Query.Locate('Line;Hour;Minute',VarArrayOf([Line-400,AHour,minuteof(Start)]),[])
我是一名优秀的程序员,十分优秀!