2012-01-20 105 views
5

我需要跟蹤在我網站上在線的用戶,這樣我才能在在線用戶的頭像旁邊顯示「在線」圖標。爲什麼我這樣做時我的MySQL查詢速度很快,而當我這樣做時速度很慢?

的檢測,第一步是跟蹤當用戶最後一次露面的,所以我每次用戶請求頁面的時間做一個UPDATE查詢:

UPDATE `users` 
SET `last_seen` = CURRENT_TIMESTAMP 
WHERE `user_id` = '$user_id' 

現在,經過這一權利,我執行另一個查詢,這一次得到我的網站的所有用戶的某些準則下,所以我可以在主頁上顯示出來:

SELECT *, 
(ACOS(SIN(0.7103989219783) * SIN(RADIANS(users.latitude)) + COS(0.7103989219783) * COS(RADIANS(users.latitude)) * COS(RADIANS(users.longitude) - -1.2894447135174)) * 6371) AS SearchRadius 
FROM `users` 
INNER JOIN `profiles` ON (
    users.user_id = profiles.user_id 
) 
WHERE (users.latitude > 38.904216788163 AND users.latitude < 42.501503211837) 
AND (users.longitude > -76.252301637251 AND users.longitude < -71.507178362749) 
AND (ACOS(SIN(0.7103989219783) * SIN(RADIANS(users.latitude)) + COS(0.7103989219783) * COS(RADIANS(users.latitude)) * COS(RADIANS(users.longitude) - -1.2894447135174)) * 6371) < 200 AND users.sex = '1' AND users.seeking = '2' AND users.user_id != '1' AND users.account_status = '1' LIMIT 0, 10 

沒關係此查詢的瘋狂,基本的一點是,我來自同一個users選擇表,我以前更新ING。

當我陸續執行這些2個查詢一個這些是我得到的時間:

1st query: 0.0392 seconds 
2nd query: 1.5396 seconds 

這會導致頁面加載時間明顯的延遲。

現在,當我創建了一個單獨的表在線用戶和第一查詢改成這樣:更快

1st query: 0.0411 seconds 
2nd query: 0.0008 seconds 

,並在頁面加載:

UPDATE `online_users` 
SET `last_seen` = CURRENT_TIMESTAMP 
WHERE `user_id` = '$user_id' 

的時代變遷到這裏!

這是爲什麼?我的猜測是,它與表鎖定有關,但我不知道足夠確定或知道更多細節。

+0

第二個查詢是否仍然返回正確的結果? –

+1

如果你運行沒有第一個查詢的第二個查詢是否更快?這可能是某種類型的I/O問題 - 我對MySQL內部沒有興趣,但不應該是那種在SQL意義上阻塞的事情,畢竟它是在同一個事務中的同一個連接上,在這種情況下,可以看到未提交的更改或更改已經提交。你在使用InnoDB還是MyISAM? –

+0

@Cade Roux如果我單獨運行第二個查詢,它會更快,但只需要0.0004分鐘。我正在使用MyISAM。 – TK123

回答

1

因爲SELECT *包括last_seen MySQL無法緩存查詢或子查詢。您可以嘗試明確列舉所有字段,但是last_seen。在InnoDB表

(但一個單獨的表online_users使多大意義。)

+0

只是通過顯式調用除last_seen之外的所有列名稱來嘗試它,並且查詢時間仍然是相同的長度。 – TK123

+0

所以我們比較聰明;只需更新同一個表即可刪除該表的_all_高速緩存的查詢數據。或者像每個表的線程分配和更新的磁盤迴寫那樣的含糊不清。 –

-4

查詢比對的MyISAM慢。 表中的更多行使查詢更慢。 表上的錯誤索引使查詢更慢,請使用EXPLAIN命令進行檢查。

0

假設SELECT查詢在測試之前運行了好幾次,您可能會看到查詢緩存的效果。表上的任何更新都會使緩存無效,並強制重新執行查詢。通過更新不同的表格,您可以避免破壞這些緩存條目。

+0

這是有道理的,但在我的情況下,我有這個查詢只執行一次,這是更新查詢後。 – TK123

+0

請注意,您可以在運行任何其他命令之前使用'SET SESSION query_cache_type = OFF;'確認此事。 (這隻會禁用當前連接的查詢緩存。) –

相關問題