2013-04-27 79 views
-1

我扫描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的“真”,无论它分配了多少次,或者我应该进行比较,并且只是第一次更改OneFuond?

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

感谢

+0

OneFound:= tbl1.FieldByName('Name')。AsString ='jones';如果OneFound然后开始...结束;将是一个更清洁恕我直言,**但**你应该考虑使用SQL你的优势。 – ComputerSaysNo 2013-04-27 17:23:57

+2

@ComputerSaysNo改变逻辑。关于'OneFound'的一点是,在循环结尾(我们看不到),如果找到一个或多个匹配,它就是“真”。 – 2013-04-27 17:33:23

+1

从您的声明中“扫描SQLite数据库寻找所有匹配项”我推断您​​正在浏览结果集中的所有记录。如果至少找到一个匹配,OneFound将被设置。你是否确定你的循环是while(不是eof())和(不是OneFound)?因为这是真正的节省时间。 – 2013-04-27 17:46:49

回答

4

你的问题是,这是更快:

if not(OneFound) then OneFound:=True; 

OneFound := True; 

答案很可能是第二快。有条件的声明涉及分支机构,可能会导致分支预测不当

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

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

+3

但与“tbl1.FieldByName('Name')”相比,它可以忽略不计。 – 2013-04-27 17:25:55

+0

@AndreasHausladen请参阅我最后一篇有关使用FTS3和虚拟表格的文章。 – user2220358 2013-04-27 18:28:08

3

最好是更改SQL语句,以便在数据库中完成工作。如果你想知道是否有包含在该领域“名”值'琼斯的一个元组,然后更快的查询是

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; 

你的语法可能会有所不同关于“限价”条款,但这个想法是从数据库返回一个元组,它与'where'语句匹配 - 哪一个并不重要。

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

0

1.搜索一个领域

如果你要搜索一个特定领域的内容,使用索引和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视为提供的文本块上的“元索引”或“全文索引”。就像google能够在数百万个网页中找到一个词:它不使用常规数据库,但是full-text indexing

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

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

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