2013-04-27 78 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過程。