P粉0091864692023-09-04 14:58:45
最快
當有電話呼入時,改變資料流以更新customers.last_call
。
更新連線
UPDATE
與JOIN
相比,IN ( SELECT ... )
效果更好。
或
OR
會降低效能。查詢很可能會為每個客戶掃描整個phone_call_log
。
一種解決方法是進行兩個UPDATE
,並使用適當的索引:
UPDATE SET customers.last_call = GREATEST( customers.last_call, ( select max(phone_call_log.start_time) FROM phone_call_log WHERE phone_call_log.callee = customers.phonenumber ) WHERE ... UPDATE SET customers.last_call = GREATEST( customers.last_call, ( ... caller ... ) ) WHERE ...
這需要在phone_call_log
上建立以下索引:
INDEX(callee, start_time) INDEX(caller, start_time)
並且刪除目前的單列索引caller和callee。
資料型別
對於電話號碼來說,使用BIGINT
可能是錯誤的,特別是考慮到LENGTH(customers.phonenumber) > 6
。
實際上,所有這些都可以歸結為一個簡單的測試:
where customers.phonenumber is not null AND LENGTH(customers.phonenumber) > 6 AND customers.phonenumber > 1000000;
每個>
檢查都會檢查NOT NULL
;根據資料類型只使用其中一個,並對其進行索引。
(請提供SHOW CREATE TABLE
;'英文'不夠準確。)
P粉3546029552023-09-04 10:38:38
使用OR
的查詢無法有效地使用索引。我建議你試試以下方法:
UPDATE customers SET last_call = GREATEST( (SELECT MAX(start_time) FROM phone_call_log WHERE callee = customers.phonenumber), (SELECT MAX(start_time) FROM phone_call_log WHERE caller = customers.phonenumber) )
請注意,GREATEST
在處理NULL值時有問題。