iT邦幫忙

0

COUNT點擊率效能問題

主table

tbl_main
m_id int
m_label varchar

點擊率table
tbl_main_hits
mh_id int
mh_ip varchar
tbl_main_fk int (tbl_main的fk)

tbl_main_hits在網友點擊該頁面,根據規則過濾無誤後即儲存一筆資料
目前要撈出前10名的語法如下,資料正確無誤,但點擊率數量過多,光第一名已經COUNT將近10萬筆
所以撈取的速度有點慢,不知道有沒有別的作法可以達到相同的目的並且改善效能

SELECT m_id, m_label
FROM tbl_main
ORDER BY (SELECT COUNT(mh_id) FROM tbl_main_hits WHERE tbl_main_hits.tbl_main_fk = tbl_main.m_id) DESC LIMIT 0, 10
fillano iT邦超人 1 級 ‧ 2010-09-08 13:45:39 檢舉
先不管解決方式,您的sql正確嗎?
不懂為什麼你的子查詢何不用個VIEW或FUNCTION存起來
如果真的會很頻繁的下這個語法的話

而且用GROUP BY 下 SELECT 本來效能就比較差
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

6
fillano
iT邦超人 1 級 ‧ 2010-09-08 14:36:10
最佳解答

建議你稍微解釋一下tbl_main及tbl_main_hits的作用,我擔心會誤會你的意思。

我看到你這樣做,是想到tbl_main可能是一個模組名稱,tbl_main_hits中儲存的點擊資料是與他關聯的。

你的sql下的真的有點奇怪...這個用group by加上left join就可以阿,並不需要sub query。如果有速度問題先把where條件跟on條件會用到的欄位加上index,如果還沒效...那看看有沒有其他問題。

如果要用qileroro建議的方法,如果結果要精確,那操作上需要做lock table(假設你是用mysiam格式的資料表)。要用select ... for update的話(row lock),需要用innodb格式的資料表,而且要用transaction,比較麻煩一點。

chan15 iT邦新手 2 級 ‧ 2010-09-08 14:38:17 檢舉

tbl_main_hits就是某人點了tbl_main的某筆資料頁面後做+1的統計
我用過LEFT JOIN GROUP BY
但平均比subqueries慢2秒

fillano iT邦超人 1 級 ‧ 2010-09-08 14:57:56 檢舉

這樣...你只能用hit+1做做看了,這樣寫入比較慢,但是讀取會更快。(反正規化)

fillano iT邦超人 1 級 ‧ 2010-09-08 15:19:51 檢舉

如果還不夠快...也不要求結果精確,那可以如qileroro建議的用緩存,例如定期把結果存到一個temporary table,然後查詢都是查詢這個table。

16
qileroro
iT邦新手 4 級 ‧ 2010-09-08 11:50:54

建议

  1. tbl_main加个hits列
  2. 查询结果缓存

我要發表回答

立即登入回答