我有「的用戶」中,「內容」的表,「content_likes」的表的表。當用戶「喜歡」某項內容時,會將關係添加到「content_likes」。簡單。
現在我想要做的是根據它收到的喜好數量來訂購內容。這是相對容易的,但是,我只想一次檢索10個項目,然後使用延遲加載,我正在檢索接下來的10個項目等等。如果select按時間順序排列,則在select語句中執行偏移量很容易,但是,由於「喜歡」數量的排序,我需要另一個列可以抵消。因此,我在結果集中添加了「排名」列,然後在下一次我可以抵消的10個項目的調用中。
這個查詢工作,並做我需要做的。但是,我擔心表現。任何人都可以建議優化此查詢。甚至可能是一個更好的方法。
DB模式
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
CREATE TABLE `content` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`owner_id` int(11) NOT NULL,
`added` int(11) NOT NULL,
`deleted` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
CREATE TABLE `content_likes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`content_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`added` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
*欄目爲簡單起見省略
查詢明細
- 組的content_id在content_likes關係表中,以便通過喜歡DESC
- 添加一列「r ank「(或行號)結果集並按此排序
- 加入」內容「表,以便可以忽略具有已刪除標誌的任何內容
- 僅返回」排名「(或行號)較大的結果比可變
- 限制結果設置爲10
MySQL的
SELECT
results.content_id, results.likes, results.rank
FROM
(
SELECT
t1.content_id, t1.likes, @rn:[email protected]+1 AS rank
FROM
(
SELECT
cl.content_id,
COUNT(cl.content_id) AS likes
FROM
content_likes cl
GROUP BY
cl.content_id
ORDER BY
likes DESC,
added DESC
) t1, (SELECT @rn:=0) t2
ORDER BY
rank ASC
) results
LEFT JOIN
content c
ON
(c.id = results.content_id)
WHERE
c.deleted <> 1
AND
results.rank > :lastRank
LIMIT
10
MYSQL ALTERNATIVE
SELECT
*
FROM
(
SELECT
results.*, @rn:[email protected]+1 AS rank
FROM
(
SELECT
c.id, cl.likes
FROM
content c
INNER JOIN
(SELECT content_id, COUNT(content_id) AS likes FROM content_likes GROUP BY content_id ORDER BY likes DESC, added DESC) cl
ON
c.id = cl.content_id
WHERE
c.deleted <> 1
AND
c.added > :timeago
LIMIT
100
) results, (SELECT @rn:=0) t2
) final
WHERE
final.rank > :lastRank
LIMIT
5
「另類」mysql查詢的工作原理,我也喜歡它。內容按用戶的喜好數排序,我可以通過插入最後一個行號來抵消。我在這裏試圖做的是限制結果集,所以如果和當表獲得大的性能不會受到太大的阻礙。在此示例中,僅返回時間範圍內的內容,並且限制爲100。然後我可以抵消行號(延遲加載/分頁)
任何幫助或建議總是讚賞。我比較到mysql一個新手,所以是一種:)
請編輯您的問題以顯示錶格的定義,包括索引。 –
嘿Ollie,完成 –
否 - 請顯示完整的結構,包括引擎,索引定義和基數。併爲該查詢提供解釋計劃(儘管即使沒有看到詳細信息,仍有大量的調整範圍)。 – symcbean