DataMagnet Performance tuning




DataMagnet 是讓客戶能夠透過 HTTP POST 傳送 JSON data 並儲存各種資訊到我們的錄影軟體 VAST2, 再透過 VAST2 來搜尋內容的功能 
客戶用我們的 data magnet 功能, 一天下來會有好幾萬筆的資料,而且內容是夾帶著 image 的 data (base64 format)
而如果這樣的 data 有幾百萬 or 幾千萬筆的資料在 db 裏頭,
雖然我們在 UI 有限制結果的筆數 (50 results/page),也不會針對 snapshot column 去搜尋
但若搜尋條件的範圍一大,例如: 1s 一筆資料,那麼半年範圍就會有高達一千五百萬筆資料,造成搜尋的速度很慢。
而且這樣的 database size 也是很驚人的,以上面的欄位來看 (include image data: 128px*128px) ,15 million 筆數的資料就高達 60G 左右的大小。

所以中間我們就找了幾種作法:
這做法有幾個流程要改:
首先 Create Table 的方式不一樣了
還有 SELECT 找 string 的方式也不一樣 (match)
也因為我們要 search 的文字是要 match prefix, middle, postfix 
原本 fts 只有 prefix mapping, 而上面的 link 跟我們說可以透過 uncompress string 的方式來做到搜尋中間的字串, 但這有幾個缺點:
  1. 每個 column 個都要多一個 column 來儲存 uncompress 的 string (除了不用搜尋的 snapshot & timestamp column), 但這會增加整個 database 的 size
  2. or 要增加 compress, uncompress function 在 Create Table 時加入 https://www.sqlite.org/fts3.html#the_compress_and_uncompress_options , 但這要直接使用 SQLite 的 API function, 對我們使用 Qt 包一層的 API 不好實作
重要的是, 我們改了一版用 fts 的 table 來搜尋, 並沒有特別的好....

2. 後來回頭想原本的瓶頸在哪, 拆解一下傳進去的內容...
看到 snapshot 的 column 其實佔了 db 很大的容量
若少了 snapshot 這欄位, 原本的 search 數度就會很快 (5~6 個月的搜尋範圍, 搜尋某個字串, 1s 左右)
所以我們就把 snapshot 的 context 想辦法不要放進去 db 裡面
改成存 snapshot 的路徑, 而將 user 傳過得來的 snapshot data 存成 binary 的路徑
這樣的好處就是搜尋速度變快好幾倍。

0 comments