我的User
表有記錄。我有更新的方法的用戶auth_token
:Rails 4 SQL Update耗時太長
def reset_auth_token
update_column(:auth_token, generate_token)
end
和generate_token
方法:
def generate_token
token = SecureRandom.urlsafe_base64(23)
User.exists?(auth_token: token) ? generate_token : token
end
(我使用update_column因爲正在生成的令牌服務器端我跳過驗證,有沒有回調,並且我不需要用戶updated_at屬性進行更改)
此方法生成的示例SQL是
User Exists (0.5ms) SELECT 1 AS one FROM "users" WHERE "users"."auth_token" = 'XA0syuJg0PGHrAHW78_S3KLGv71_kqY' LIMIT 1
SQL (6.3ms) UPDATE "users" SET "auth_token" = 'XA0syuJg0PGHrAHW78_S3KLGv71_kqY' WHERE "users"."id" = 3
6.3ms !!!只有5個記錄。我已經檢查過,確保沒有爲這個數據庫表啓用觸發器,並且我在auth_token
屬性上添加了一個索引(因爲我經常根據該屬性檢查用戶是否存在)。爲什麼更新需要這麼長時間,其他可能的解釋是什麼?
UPDATE
至於建議,我跑的解釋一下:
EXPLAIN UPDATE users SET auth_token = 'foo' WHERE id = '1';
QUERY PLAN
---------------------------------------------------------------------------------
Update on users (cost=0.14..8.15 rows=1 width=4167)
-> Index Scan using users_pkey on users (cost=0.14..8.15 rows=1 width=4167)
Index Cond: (id = 1)
(3 rows)
'解釋(緩衝區,分析)'查詢。我的第一個想法是嚴重的表膨脹。你有沒有機會去關閉PostgreSQL中的autovacuum或以其他方式搞砸了它?我的另一個想法是,在您首次發佈更新時,其他會話鎖定了它。 – 2014-09-19 04:47:48
@CraigRinger我更新了我的答案以顯示解釋的結果。我沒有碰過Postgres,甚至放棄了我的數據庫並重新創建它,以確保沒有其他事情發生。我不明白在你第一次發佈更新時「其他會話鎖定了它」部分? – kittyminky 2014-09-19 06:58:51