我问wrong question所以我会再试一次(对不起)。您不必详细阅读查询,只是为了给您一个想法。
无论如何:有问题的查询是由Doctrine2生成的(我剪切SELECT
部分)
FROM
tbl_story t0_
LEFT JOIN tbl_user t1_ ON t0_.creator_id = t1_.id
LEFT JOIN tbl_image t2_ ON t1_.avatar_id = t2_.id
LEFT JOIN tbl_image t3_ ON t0_.id = t3_.story_id
LEFT JOIN tbl_like t4_ ON t0_.id = t4_.story_id AND (t4_.creator_id = 3)
LEFT JOIN tbl_comment t5_ ON t0_.id = t5_.story_id
LEFT JOIN tbl_like t6_ ON t5_.id = t6_.comment_id AND (t6_.creator_id = 3)
LEFT JOIN tbl_user t7_ ON t5_.creator_id = t7_.id
LEFT JOIN tbl_image t8_ ON t7_.avatar_id = t8_.id
LEFT JOIN tbl_location_city t9_ ON t0_.city_id = t9_.id
LEFT JOIN tbl_location_state t10_ ON t9_.state_id = t10_.id
LEFT JOIN tbl_location_country t11_ ON t10_.country_id = t11_.id
LEFT JOIN tbl_story t12_ ON t0_.parent_id = t12_.id
LEFT JOIN tbl_page t13_ ON t0_.page_id = t13_.id
LEFT JOIN tbl_page_type t14_ ON t13_.page_type_id = t14_.id
LEFT JOIN tbl_story_tag t25_ ON t0_.id = t25_.story_id
LEFT JOIN tbl_tag t15_ ON t15_.id = t25_.tag_id
LEFT JOIN tbl_story_linked_user_reference t16_ ON t0_.id = t16_.story_id
LEFT JOIN tbl_user t17_ ON t16_.user_id = t17_.id
LEFT JOIN tbl_image t18_ ON t17_.avatar_id = t18_.id
LEFT JOIN tbl_story t19_ ON t0_.id = t19_.parent_id
LEFT JOIN tbl_album t20_ ON t0_.parent_album_id = t20_.id
LEFT JOIN tbl_image t21_ ON t20_.id = t21_.album_id
LEFT JOIN tbl_image_linked_user t22_ ON t21_.id = t22_.image_id
LEFT JOIN tbl_user t23_ ON t22_.user_id = t23_.id
LEFT JOIN tbl_image t24_ ON t23_.avatar_id = t24_.id
WHERE (
t0_.creator_id = 3
OR t0_.id IN
(SELECT
t26_.id
FROM tbl_story t26_
INNER JOIN tbl_story_circle_visibility t28_ ON t26_.id = t28_.story_id
INNER JOIN tbl_circle t27_ ON t27_.id = t28_.circle_id
INNER JOIN tbl_user_circle_reference t29_ ON t27_.id = t29_.circle_id
AND (t29_.user_id = 3))
OR t0_.is_public = 1
)
AND t0_.is_draft = 0
AND t0_.type IN (0, 3, 2, 21)
ORDER BY t0_.created_at DESC
LIMIT 7
问题:
使用ORDER BY
,当tbl_story(主查询)中只有31.000行时,查询需要1.2秒才能执行。如果我删除ORDER BY
,它会在6ms内执行,我想所有这些连接需要额外的时间,但仍然无需担心。
我首先thought ORDER BY
很慢,但我错了。我试过了
SELECT * FROM `tbl_story` ORDER BY created_at DESC LIMIT 7
(同样但没有连接)并且它在2ms内执行。
我也阅读了其他问题,包括this one,建议删除JOIN
个部分。如果我在Doctrine2中可以做到这一点,那可能会有用:
$queryBuilder->select("o.id")->removeLeftJoins()
在我获取ID之后,使用它们克隆原始查询。
如何解决分页问题?
注:
即使我完全删除WHERE
子句,查询也会花费相同的1.2秒,因此不会出现问题。
感谢。
答案 0 :(得分:0)
我怀疑对type和is_draft进行索引可能不会缩小范围,以便MySQL不会注意到这些索引。
如果你有一个关于creator_id的索引,另一个关于is_public而另一个关于id(我假设你这样做,因为它可能是主要的id),那么这样的3个联合查询可能会有所帮助。
SELECT *
FROM
tbl_story t0_
LEFT JOIN tbl_user t1_ ON t0_.creator_id = t1_.id
LEFT JOIN tbl_image t2_ ON t1_.avatar_id = t2_.id
LEFT JOIN tbl_image t3_ ON t0_.id = t3_.story_id
LEFT JOIN tbl_like t4_ ON t0_.id = t4_.story_id AND (t4_.creator_id = 3)
LEFT JOIN tbl_comment t5_ ON t0_.id = t5_.story_id
LEFT JOIN tbl_like t6_ ON t5_.id = t6_.comment_id AND (t6_.creator_id = 3)
LEFT JOIN tbl_user t7_ ON t5_.creator_id = t7_.id
LEFT JOIN tbl_image t8_ ON t7_.avatar_id = t8_.id
LEFT JOIN tbl_location_city t9_ ON t0_.city_id = t9_.id
LEFT JOIN tbl_location_state t10_ ON t9_.state_id = t10_.id
LEFT JOIN tbl_location_country t11_ ON t10_.country_id = t11_.id
LEFT JOIN tbl_story t12_ ON t0_.parent_id = t12_.id
LEFT JOIN tbl_page t13_ ON t0_.page_id = t13_.id
LEFT JOIN tbl_page_type t14_ ON t13_.page_type_id = t14_.id
LEFT JOIN tbl_story_tag t25_ ON t0_.id = t25_.story_id
LEFT JOIN tbl_tag t15_ ON t15_.id = t25_.tag_id
LEFT JOIN tbl_story_linked_user_reference t16_ ON t0_.id = t16_.story_id
LEFT JOIN tbl_user t17_ ON t16_.user_id = t17_.id
LEFT JOIN tbl_image t18_ ON t17_.avatar_id = t18_.id
LEFT JOIN tbl_story t19_ ON t0_.id = t19_.parent_id
LEFT JOIN tbl_album t20_ ON t0_.parent_album_id = t20_.id
LEFT JOIN tbl_image t21_ ON t20_.id = t21_.album_id
LEFT JOIN tbl_image_linked_user t22_ ON t21_.id = t22_.image_id
LEFT JOIN tbl_user t23_ ON t22_.user_id = t23_.id
LEFT JOIN tbl_image t24_ ON t23_.avatar_id = t24_.id
WHERE t0_.creator_id = 3
AND t0_.is_draft = 0
AND t0_.type IN (0, 3, 2, 21)
UNION
SELECT *
FROM
tbl_story t0_
LEFT JOIN tbl_user t1_ ON t0_.creator_id = t1_.id
LEFT JOIN tbl_image t2_ ON t1_.avatar_id = t2_.id
LEFT JOIN tbl_image t3_ ON t0_.id = t3_.story_id
LEFT JOIN tbl_like t4_ ON t0_.id = t4_.story_id AND (t4_.creator_id = 3)
LEFT JOIN tbl_comment t5_ ON t0_.id = t5_.story_id
LEFT JOIN tbl_like t6_ ON t5_.id = t6_.comment_id AND (t6_.creator_id = 3)
LEFT JOIN tbl_user t7_ ON t5_.creator_id = t7_.id
LEFT JOIN tbl_image t8_ ON t7_.avatar_id = t8_.id
LEFT JOIN tbl_location_city t9_ ON t0_.city_id = t9_.id
LEFT JOIN tbl_location_state t10_ ON t9_.state_id = t10_.id
LEFT JOIN tbl_location_country t11_ ON t10_.country_id = t11_.id
LEFT JOIN tbl_story t12_ ON t0_.parent_id = t12_.id
LEFT JOIN tbl_page t13_ ON t0_.page_id = t13_.id
LEFT JOIN tbl_page_type t14_ ON t13_.page_type_id = t14_.id
LEFT JOIN tbl_story_tag t25_ ON t0_.id = t25_.story_id
LEFT JOIN tbl_tag t15_ ON t15_.id = t25_.tag_id
LEFT JOIN tbl_story_linked_user_reference t16_ ON t0_.id = t16_.story_id
LEFT JOIN tbl_user t17_ ON t16_.user_id = t17_.id
LEFT JOIN tbl_image t18_ ON t17_.avatar_id = t18_.id
LEFT JOIN tbl_story t19_ ON t0_.id = t19_.parent_id
LEFT JOIN tbl_album t20_ ON t0_.parent_album_id = t20_.id
LEFT JOIN tbl_image t21_ ON t20_.id = t21_.album_id
LEFT JOIN tbl_image_linked_user t22_ ON t21_.id = t22_.image_id
LEFT JOIN tbl_user t23_ ON t22_.user_id = t23_.id
LEFT JOIN tbl_image t24_ ON t23_.avatar_id = t24_.id
WHERE t0_.id IN
(SELECT
t26_.id
FROM tbl_story t26_
INNER JOIN tbl_story_circle_visibility t28_ ON t26_.id = t28_.story_id
INNER JOIN tbl_circle t27_ ON t27_.id = t28_.circle_id
INNER JOIN tbl_user_circle_reference t29_ ON t27_.id = t29_.circle_id
AND (t29_.user_id = 3))
AND t0_.is_draft = 0
AND t0_.type IN (0, 3, 2, 21)
UNION
SELECT *
FROM
tbl_story t0_
LEFT JOIN tbl_user t1_ ON t0_.creator_id = t1_.id
LEFT JOIN tbl_image t2_ ON t1_.avatar_id = t2_.id
LEFT JOIN tbl_image t3_ ON t0_.id = t3_.story_id
LEFT JOIN tbl_like t4_ ON t0_.id = t4_.story_id AND (t4_.creator_id = 3)
LEFT JOIN tbl_comment t5_ ON t0_.id = t5_.story_id
LEFT JOIN tbl_like t6_ ON t5_.id = t6_.comment_id AND (t6_.creator_id = 3)
LEFT JOIN tbl_user t7_ ON t5_.creator_id = t7_.id
LEFT JOIN tbl_image t8_ ON t7_.avatar_id = t8_.id
LEFT JOIN tbl_location_city t9_ ON t0_.city_id = t9_.id
LEFT JOIN tbl_location_state t10_ ON t9_.state_id = t10_.id
LEFT JOIN tbl_location_country t11_ ON t10_.country_id = t11_.id
LEFT JOIN tbl_story t12_ ON t0_.parent_id = t12_.id
LEFT JOIN tbl_page t13_ ON t0_.page_id = t13_.id
LEFT JOIN tbl_page_type t14_ ON t13_.page_type_id = t14_.id
LEFT JOIN tbl_story_tag t25_ ON t0_.id = t25_.story_id
LEFT JOIN tbl_tag t15_ ON t15_.id = t25_.tag_id
LEFT JOIN tbl_story_linked_user_reference t16_ ON t0_.id = t16_.story_id
LEFT JOIN tbl_user t17_ ON t16_.user_id = t17_.id
LEFT JOIN tbl_image t18_ ON t17_.avatar_id = t18_.id
LEFT JOIN tbl_story t19_ ON t0_.id = t19_.parent_id
LEFT JOIN tbl_album t20_ ON t0_.parent_album_id = t20_.id
LEFT JOIN tbl_image t21_ ON t20_.id = t21_.album_id
LEFT JOIN tbl_image_linked_user t22_ ON t21_.id = t22_.image_id
LEFT JOIN tbl_user t23_ ON t22_.user_id = t23_.id
LEFT JOIN tbl_image t24_ ON t23_.avatar_id = t24_.id
WHERE t0_.is_public = 1
AND t0_.is_draft = 0
AND t0_.type IN (0, 3, 2, 21)
ORDER BY t0_.created_at DESC
LIMIT 7