不断分配值或比较是否更快

时间:2013-04-27 17:15:38

标签: delphi boolean-operations

我正在扫描SQLite数据库,查找所有匹配项并使用

OneFound:=False;
if tbl1.FieldByName('Name').AsString = 'jones' then
begin
  OneFound:=True;
  tbl1.Next;
end;
if OneFound then // Do something

或者我应该使用

if not(OneFound) then OneFound:=True;

将OneFound分配给“True”是否更快,无论分配了多少次,或者我应该进行比较并且只是第一次更改OneFuond?

我知道更好的方法是使用FTS3,但是现在我必须扫描数据库,问题更多的是关于设置OneFound的方法,因为遇到匹配或使用比较方法和设置它只是一次。

由于

3 个答案:

答案 0 :(得分:4)

你的问题是,更快:

if not(OneFound) then OneFound:=True;

OneFound := True;

答案可能是第二个更快。条件语句涉及分支,这可能会导致分支错误预测。

然而,与周围的代码相比,这行代码是微不足道的。一次一行地运行数据库将是非常昂贵的。我敢打赌,你将无法衡量两个选项之间的差异,因为那个小Boolean的处理只是被其余的代码所淹没。在这种情况下,选择更易读和更简单的版本。

但是,如果您关心此代码的性能,您应该要求数据库完成工作,就像您自己所说的那样。写一个查询来执行工作。

答案 1 :(得分:3)

最好更改SQL语句,以便在数据库中完成工作。如果你想知道在'name'字段中是否有一个包含值'jones'的元组,那么更快的查询将是

with tquery.create (nil) do
 begin
  sql.add ('select name from tbl1 where name = :p1 limit 1');
  sql.params[0].asstring:= 'jones';
  open;
  onefound:= not isempty;
  close;
  free
 end;

关于'limit'子句,你的语法可能有所不同,但想法是从数据库中只返回一个元组,它与'where'语句匹配 - 无论哪一个都无关紧要。

我使用了一个参数来避免分隔值的问题。

答案 2 :(得分:0)

<强> 1。搜索一个字段

如果要搜索一个特定的字段内容,使用INDEX和SELECT将是最快的。

   SELECT * FROM MYTABLE WHERE NAME='Jones';

不要忘记先在列上创建一个INDEX!

<强> 2。快速阅读

但是如果你想在字段中搜索,或者在几个字段中搜索,你可能需要阅读并检查整个内容。在这种情况下,对于每个数据行,调用FieldByName()的速度会很慢:最好使用本地TField变量。

或者忘记TDataSet,然后切换到直接访问SQLite3。事实上,使用DB.pasTDataSet需要大量数据编组,因此比直接访问要慢。

参见例如DiSQLite3或我们的DB classes,它们非常快,但有点高级。或者您可以在这些类之上使用我们的ORM。我们的类能够read more than 500,000 rows per second from a SQLite3 database,包括JSON编组到对象字段中。

第3。 FTS3 / FTS4

但是,正如您所猜测的那样,最快的确是使用FTS3/FTS4 feature of SQlite3

您可以将FTS4 / FTS4视为所提供的文本blob上的“元索引”或“全文索引”。就像谷歌能够在数百万个网页中找到一个词:它不使用常规数据库,而是使用full-text indexing

简而言之,您在数据库中创建了一个虚拟FTS3 / FTS4表,然后在此表中插入FTS TEXT字段中主记录的全文,强制ID字段为原始数据行之一

然后,您将在FTS3 / FTS4表上查询一些单词,这将为您提供匹配的ID,比常规扫描快得多。

请注意,我们的ORM有专门的TSQLRecordFTS3 / TSQLRecordFTS4类用于直接FTS流程。