1

[site_list] ~100,000 行... 10mb 大小。

  • site_id
  • 网站网址
  • site_data_most_recent_record_id

[site_list_data] ~ 15+ 百万行并且还在增长......大小约为 600mb。

  • 记录ID
  • site_id
  • 站点连接时间
  • 站点速度
  • 日期检查

粗体列是唯一的索引键。

我需要返回 50 个最近更新的站点以及与之相关的最新数据 - 连接时间、速度、日期......
这是我的查询:

SELECT SQL_CALC_FOUND_ROWS
  site_list.site_url,
  site_list_data.site_connect_time,
  site_list_data.site_speed,
  site_list_data.date_checked
FROM site_list
  LEFT JOIN site_list_data
    ON site_list.site_data_most_recent_record_id = site_list_data.record_id
ORDER BY site_data.date_checked DESC
LIMIT 50

如果没有 ORDER BY 和 SQL_CALC_FOUND_ROWS(我需要它进行分页),查询大约需要 1.5 秒,而那些需要超过 2 秒或更长时间的查询还不够好,因为将显示此数据的特定页面正在获得 20K+ 页面浏览量/一天,这个查询显然太重了(当我把它上线时服务器几乎死了)而且太慢了。

mySQL的专家,你会怎么做?如果表达到 1 亿条记录怎么办?每 30 秒将这个巨大的结果缓存到临时表中是我得到的唯一其他解决方案。

4

3 回答 3

2

您需要向查询添加启发式。您需要对查询进行门控以获得合理的性能。它有效地按日期降序对您的 site_list_date 表进行排序——整个表。

因此,如果您知道前 50 名将在最后一天或一周内,请在查询中添加“and date_checked > <boundary_date>”。然后它应该首先减少整体结果集,然后对其进行排序。

于 2013-01-27T04:34:44.300 回答
1

SQL_CALC_ROWS_FOUND 是慢速使用 COUNT 代替。看看这里

于 2013-01-27T05:04:30.693 回答
1

一些观察。

两者ORDER BY都会SQL_CALC_FOUND_ROWS增加你的表演成本。 ORDER BY可以通过适当的索引来改进子句——你的 date_checked 列上有索引吗?这可能会有所帮助。

您的确切需求是SQL_CALC_FOUND_ROWS什么?考虑用一个单独的查询替换它COUNT。假设您的查询缓存已启用,这可能会好得多。

如果您可以使用COUNT,请考虑将您的替换LEFT JOIN为 an INNER JOIN,因为这也有助于提高性能。

祝你好运。

于 2013-01-27T05:29:47.637 回答