2010-08-28 65 views
4

我需要確定用戶是否已經訪問了一個頁面,以便跟蹤唯一頁面瀏覽量。優化SQL以確定每個用戶的獨特頁面瀏覽量

我已經實現了一些HTTP頭緩存,但現在我需要優化SQL查詢。

的訪問是獨特的,當:

  • 對:page_id + user_idvisit表中找到
  • 或對:page_id + session_id發現
  • 或:page_id + [ip + useragent ] - (這是另一個討論的話題,不管它應該是ip還是ip + useragent)

所以我有一個表,跟蹤用戶訪問:

visit: 
    page_id 
    user_id 
    session_id 
    useragent 
    ip 
    created_at 
    updated_at 

現在每個用戶訪問(不命中的Cache),如果存在的話,我會更新一行。如果有任何受影響的行,我會插入新的訪問表。

這是一個或兩個查詢(假設緩存將工作,主要是兩個查詢),但行數受限於某種方式。也許最好是將所有的都存儲下來,然後在數據庫中清理數據庫。一個月?

的問題是:

  • 如何應該是visit表結構(鍵,索引,關係到userpage_views表)。一些重要的字段可能爲空(例如user_id),那麼索引呢?我需要多列主鍵嗎?
  • 這將是最快的SQL查詢來找到唯一的用戶?
  • 是這種理智的方法嗎?

我使用PostgreSQL和PDO(Doctrine ORM)。 我所有的會話都存儲在同一個數據庫中。

回答

2

個人而言,我不會把這個請求 - 響應路徑。我會將原始數據記錄在一個表中(或將它推送到一個隊列中),並讓後臺任務/線程/ cron作業處理。

隊列(或消息傳遞表)應該包含pageid,userip,sessionid,useragen,ip。

只要後臺任務能夠跟上,絕對時間就不那麼重要了。因爲單個線程現在可以完成繁重的工作,所以在更新獨特的綜合瀏覽量表時不會產生衝突的鎖定。

+0

嗨,如果我使用隊列,我將如何知道我是否已經處理了一個唯一的用戶?我必須使用另一個數據庫來存儲「已計數的用戶」嗎? – moeseth 2017-03-05 14:06:32

+0

@moeseth不,隊列只是爲了將工作從請求線程移開,所以響應不會延遲。您可以使用任何業務規則來檢測唯一的用戶頁面查看,以分隔監聽隊列的後臺工作人員中的唯一用戶。 – 2017-03-08 10:59:06

+0

我相信我將不得不使用存儲系統來檢測「已計數的用戶」。是對的嗎? – moeseth 2017-03-09 06:20:27

0

只是一些隨機的想法:

我可以驗證獨特的訪問類型背後的思想是:

  1. 的pageid +用戶id =用戶已登錄
  2. 的pageid +會話ID =用戶無法識別但啓用的餅乾
  3. 的pageid + IP /用戶代理=用戶無法識別,沒有啓用Cookie

對於原始性能,您可能會認爲#2是多餘的,因爲#3將會是可能是第二種情況我是大多數條件(或者是#2重要的例如如果用戶然後註冊,然後#2可以映射到#1)?(這意味着會話ID可能仍然會被記錄下來,但不會在任何訪問決定中使用)

恕我直言,IP將始終存在(即使欺騙),並且將成爲索引的理想候選者。用戶代理可以隱藏,只有有限的範圍(不是很可選)。

由於可以爲空的字段,並且由於沒有任何字段本身是唯一的,所以我會在此實例中使用代理主鍵。

恕我直言,你對存儲所有訪問,然後修剪通過批處理的重複出來是一個很好的權衡(而不是檢查是否存在更新VS插入新)

  • 所以PK =代孕
  • 想法
  • 集羣=不確定 - 另一個查詢/需求可能會改善這一點。
  • 非聚集索引= IP地址,網頁ID(假設除頁面ID的更鮮明的IP地址)
相關問題