我正在查询新闻网站,该网站会在主页上找到要显示的要点。以这种方式标记的内容被标记为“FeaturedContent”,并在“主页”的特色表格中排序。我目前有所需的输出,但查询运行超过3秒,我需要减少。如何优化查询,如下所示?
编辑:按照建议每分钟实现视图,直到.4秒:
SELECT f.position, s.item_id, s.item_type, s.title, s.caption, s.date
FROM live.search_all s
INNER JOIN live.tags t
ON s.item_id = t.item_id AND s.item_type = t.item_type AND t.tag = 'FeaturedContent'
LEFT OUTER JOIN live.featured f
ON s.item_id = f.item_id AND s.item_type = f.item_type AND f.feature_type = 'homepage'
ORDER BY position IS NULL, position ASC, date
按顺序返回所有主页功能,然后按日期排序其他精选内容 解释如下:
|-id---|-select_type-|-table-|-type---|-possible_keys---------|-key--------|-key_len-|-ref---------------------------------------|-rows--|-Extra-------------------------------------------------------------|
|-1----|-SIMPLE------|-t2----|-ref----|-PRIMARY,tag_index-----|-tag_index--|-303-----|-const-------------------------------------|-2-----|-Using where; Using index; Using temporary; Using filesort;--------|
|-1----|-SIMPLE------|-t-----|-ref----|-PRIMARY---------------|-PRIMARY----|-4-------|-newswires.t2.id---------------------------|-1974--|-Using index-------------------------------------------------------|
|-1----|-SIMPLE------|-s-----|-eq_ref-|-PRIMARY, search_index-|-PRIMARY----|-124-----|-newswires.t.item_id,newswires.t.item_type-|-1-----|-------------------------------------------------------------------|
|-1----|-SIMPLE------|-f-----|-index--|-NULL------------------|-PRIMARY----|-190-----|-NULL--------------------------------------|-13----|-Using index-------------------------------------------------------|
简介如下:
|-Status---------------|-Time-----|
|-starting-------------|-0.000091-|
|-Opening tables-------|-0.000756-|
|-System lock----------|-0.000005-|
|-Table lock-----------|-0.000008-|
|-init-----------------|-0.000004-|
|-checking permissions-|-0.000001-|
|-checking permissions-|-0.000001-|
|-checking permissions-|-0.000043-|
|-optimizing-----------|-0.000019-|
|-statistics-----------|-0.000127-|
|-preparing------------|-0.000023-|
|-Creating tmp table---|-0.001802-|
|-executing------------|-0.000001-|
|-Copying to tmp table-|-0.311445-|
|-Sorting result-------|-0.014819-|
|-Sending data---------|-0.000227-|
|-end------------------|-0.000002-|
|-removing tmp table---|-0.002010-|
|-end------------------|-0.000005-|
|-query end------------|-0.000001-|
|-freeing items--------|-0.000296-|
|-logging slow query---|-0.000001-|
|-cleaning up----------|-0.000007-|
我刚开始阅读EXPLAIN输出,所以我不确定我是否有更好的订购,或者可以采取任何相当简单的措施来加快这些速度。
search_all表是物化视图表,它定期更新,而标签和特色表是视图。这些视图不是可选的,无法解决。
标签视图根据item_type和item_id组合标签和关系表以获取标签列表,但其他视图都是一个表的简单视图。
编辑:使用物化视图,最大的瓶颈似乎是“复制到临时表”步骤。没有订购输出,它需要.0025秒(好多了!),但最终输出确实需要订购。有没有办法提高该步骤的性能,或解决它?
很抱歉,如果格式化难以阅读,我很新,不确定如何定期完成。
谢谢你的帮助!如果还有其他需要,请告诉我!
编辑:表格大小,供参考:
标签关系:197,411
标签:16,897
故事:51,801
图像:28,383
视频:2,408
特色:13
答案 0 :(得分:1)
我认为单独优化查询不会非常有用。首先想到的是,加入由UNION制成的子查询,仅仅是性能的双重瓶颈。
如果您可以选择更改数据库结构,那么我建议将3个表stories
,images
和videos
合并为一个,如果它们是,则看起来像喜欢,非常相似(添加type ENUM('story', 'image', 'video')
)来区分记录;这将删除子查询和联合。
此外,您对stories
和videos
的观看次数似乎没有使用索引字段来过滤内容。您在查询索引列吗?
在不了解您的完整表结构和数据重新分区的情况下,这是一个非常棘手的问题!
另一个选项,不涉及对现有数据库进行修改(特别是如果它已经在生产中),将“缓存”此信息到另一个表中,该表将由cron作业定期刷新。
缓存可以在完整查询或其子部分(独立视图,或3个联合合并到单个缓存表等)的不同级别完成。
此选项的可行性取决于是否可以显示稍微过时的数据。对于数据的某些部分,这可能是可以接受的,这可能意味着您将仅缓存查询中涉及的表/视图的子集。