我有一个大查询,其中包含我在我的应用中列出的Feed所需的相同类型。现在问题是这个查询不是很快。我认为,如果我限制每个人的联盟,它可能会加快一点,但我不确定。
所以基本上我的问题是如何优化此查询以更快地执行?
SELECT DISTINCT
alert_id,
uniquekey,
type,
user_id,
date_added
FROM
(
( SELECT
r.alert_id,
r.alert_id AS uniquekey,
'reply' AS `type`,
r.user_id,
r.date_added
FROM
`reply` r
LEFT JOIN `alerts` a
ON r.alert_id = a.alert_content_id
WHERE
r.user_id = :id
AND a.hide = '0'
ORDER BY
date_added DESC )
UNION
( SELECT
r.alert_id,
r.alert_id AS uniquekey,
'replyfromfollowing' AS `type`,
r.user_id,
r.date_added
FROM
`reply` r
LEFT JOIN `alerts` a
ON r.alert_id = a.alert_content_id
WHERE
r.user_id IN( '$followingstring' )
AND a.hide = '0'
ORDER BY date_added DESC )
UNION
( SELECT
i.alert_id,
i.alert_id AS uniquekey,
'liked' AS `type`,
i.user_id,
i.date_added
FROM
`interactions` i
LEFT JOIN `alerts` a
ON i.alert_id = a.alert_content_id
WHERE
i.user_id = :id
AND a.hide = '0'
GROUP BY
alert_id
ORDER BY
date_added DESC )
UNION
( SELECT
i.alert_id,
i.alert_id AS uniquekey,
'likedfromfollowing' AS `type`,
i.user_id,
i.date_added
FROM
`interactions` i
LEFT JOIN `alerts` a
ON i.alert_id = a.alert_content_id
WHERE
i.user_id IN ( '$followingstring' )
AND a.hide = '0'
GROUP BY
alert_id
ORDER BY
date_added DESC )
UNION
( SELECT
alerts as alert_id,
alert_content_id AS uniquekey,
'following' AS `type`,
user_id,
date_added
FROM
alerts a
LEFT JOIN `alerts_content` ac
ON ac.id = a.alert_content_id
WHERE
a.user_id IN ( '$followingstring' )
AND ac.anoniem = '0'
AND a.hide = '0'
GROUP BY
alert_id
ORDER BY
date_added DESC )
) joined
GROUP BY
uniquekey
ORDER BY
date_added DESC
LIMIT
".(int)$start.",20"
表格结构
Reply table Structure:
id
user_id
alert_id
description
reply_on_alert
reply_on_reply
date_added
Interaction table Structure:
id
alert_id
action_id
reply_id
user_id
date_added
Alerts table structure(Yes i know BIG mistake naming `id` : `alerts`):
alerts
title
alert_content_id
user_id
cat
lat
lon
state
hide
date_added
alerts_content table structure:
id
alert_id
description
img
查询结果:
Array
(
[0] => Array
(
[alert_id] => 173404
[uniquekey] => 173404
[type] => reply
[user_id] => 2
[date_added] => 2015-06-01 16:34:16
)
[1] => Array
(
[alert_id] => 172174
[uniquekey] => 172174
[type] => replyfromfollowing
[user_id] => 1380
[date_added] => 2015-06-01 16:01:04
)
[2] => Array
(
[alert_id] => 171772
[uniquekey] => 171772
[type] => liked
[user_id] => 2
[date_added] => 2015-06-01 15:58:44
)
[3] => Array
(
[alert_id] => 149423
[uniquekey] => 149423
[type] => reply
[user_id] => 2
[date_added] => 2015-06-01 15:25:56
)
[4] => Array
(
[alert_id] => 164742
[uniquekey] => 164742
[type] => reply
[user_id] => 2
[date_added] => 2015-05-12 09:46:39
)
[5] => Array
(
[alert_id] => 163344
[uniquekey] => 163344
[type] => replyfromfollowing
[user_id] => 3
[date_added] => 2015-05-12 09:44:46
)
[6] => Array
(
[alert_id] => 164205
[uniquekey] => 164205
[type] => liked
[user_id] => 2
[date_added] => 2015-05-11 11:06:39
)
[7] => Array
(
[alert_id] => 160890
[uniquekey] => 160890
[type] => replyfromfollowing
[user_id] => 1380
[date_added] => 2015-05-08 14:29:34
)
[8] => Array
(
[alert_id] => 163002
[uniquekey] => 163002
[type] => replyfromfollowing
[user_id] => 1380
[date_added] => 2015-05-08 13:31:12
)
[9] => Array
(
[alert_id] => 159123
[uniquekey] => 159123
[type] => replyfromfollowing
[user_id] => 48
[date_added] => 2015-04-30 15:10:32
)
[10] => Array
(
[alert_id] => 150546
[uniquekey] => 150546
[type] => replyfromfollowing
[user_id] => 16
[date_added] => 2015-04-21 21:52:49
)
[11] => Array
(
[alert_id] => 149497
[uniquekey] => 149497
[type] => reply
[user_id] => 2
[date_added] => 2015-04-10 15:19:06
)
[12] => Array
(
[alert_id] => 141078
[uniquekey] => 141078
[type] => liked
[user_id] => 2
[date_added] => 2015-04-10 15:15:32
)
[13] => Array
(
[alert_id] => 125466
[uniquekey] => 125466
[type] => replyfromfollowing
[user_id] => 3
[date_added] => 2015-04-09 00:15:22
)
[14] => Array
(
[alert_id] => 134592
[uniquekey] => 134592
[type] => replyfromfollowing
[user_id] => 3
[date_added] => 2015-04-09 00:11:04
)
[15] => Array
(
[alert_id] => 124194
[uniquekey] => 124194
[type] => likedfromfollowing
[user_id] => 3
[date_added] => 2015-04-09 00:08:35
)
[16] => Array
(
[alert_id] => 128645
[uniquekey] => 128645
[type] => likedfromfollowing
[user_id] => 3
[date_added] => 2015-04-09 00:07:29
)
[17] => Array
(
[alert_id] => 144867
[uniquekey] => 144867
[type] => replyfromfollowing
[user_id] => 3
[date_added] => 2015-04-06 13:59:19
)
[18] => Array
(
[alert_id] => 133355
[uniquekey] => 133355
[type] => liked
[user_id] => 2
[date_added] => 2015-03-31 16:16:15
)
[19] => Array
(
[alert_id] => 141075
[uniquekey] => 141075
[type] => liked
[user_id] => 2
[date_added] => 2015-03-30 15:17:01
)
)
答案 0 :(得分:1)
一些可能性,没有特别的顺序:
优化#1:
在子查询中也使用LIMIT
。但是,由于您使用的是OFFSET
,因此可能并不明白如何操作。
在查询之前,计算$ start + 20并将其放入,例如$ limit。然后使用LIMIT $limit
进行内部查询。不,不要在他们身上使用OFFSET
。这可以保证您从每个查询中获得足够的行以满足外部OFFSET $start LIMIT 20
。
优化#2:
重组表格,以便您不需要JOIN
到另一个表格(alerts
)以查明是否显示记录。也就是说,hide
阻止了许多潜在的优化。在进一步建议之前,我们需要了解LEFT
的必要性。 reply
等中的行是否在alerts
中?如果没有,请删除LEFT
并查看搜索alerts with the
OFFSET and
LIMIT`,然后加入其他4个表。
优化#3:
重组数据,以便有一个核心表,其中alerts
和其他4个表挂在上面。请确保在此新表中包含此查询所需的大多数(全部?)字段。
优化#4:
当前结构要求在考虑OFFSET
和LIMIT
之前对4个表中的每个表进行全面扫描。这闻起来像"分页&#34 ;;是吗?为了优化"分页",目标是避免表格扫描和OFFSET
;而是记住你离开的地方"这样查询就可以
WHERE ... AND x < $left_off
ORDER by x DESC
LIMIT 20
这应该可以只读取20行,而不是整个表。这将使查询更多更快,尤其是对于以后的页面。 (OFFSET
更大的时间会花费更多的时间。)
我在my blog讨论分页优化。