在分析慢查询之前,您需要找到它们。
MySQL 有一个内置的慢查询日志。 要使用它,请打开 my.cnf 文件并将 slow_query_log 变量设置为 "On"。 将 long_query_time 设置为查询被视为慢查询所需的秒数,例如 0.2。 将 slow_query_log_file 设置为您要保存文件的路径。 然后运行您的代码,任何高于指定阈值的查询都将被添加到该文件中。
一旦你知道哪些是慢查询,你可以开始探索是什么使它们变慢。 MySQL 提供的一个工具是 EXPLAIN 关键字。 它适用于 SELECT, DELETE, INSERT, REPLACE, 和 UPDATE 语句。 您只需像这样在查询前添加前缀
EXPLAIN SELECT picture.id, picture.title
FROM picture
LEFT JOIN album ON picture.album_id = album.id
WHERE album.user_id = 1;
您得到的结果是对数据访问方式的解释。 您会看到查询中涉及的每个表的一行
这里重要的部分是表名,使用的键以及查询执行期间扫描的行数。
它扫描了 2,000,000 张图片,然后,对于每张图片,它扫描了 20,000 个相册。 这意味着它实际上扫描了 album 表的 400 亿行。 但是,您可以使此过程更加高效。
索引
您可以通过使用索引来显着提高性能。 将数据视为地址簿中的名称。 您可以翻阅所有页面,也可以拉动正确的字母标签以快速找到所需的名称。
使用索引避免不必要地遍历表。 例如,您可以像这样在 picture.album_id 上添加索引
ALTER TABLE picture ADD INDEX(album_id);
现在,如果您运行查询,该过程不再涉及扫描整个图片列表。 首先,扫描所有相册以查找属于用户的相册。 之后,使用索引的 album_id 列快速定位图片。 这将扫描的行数减少到 200,000。 查询速度也比原来快 317 倍。
您可以通过添加以下索引来确保两个表都使用键
ALTER TABLE album ADD INDEX(user_id);
这次,album 表没有被完整扫描,而是使用 user_id 键快速准确定位了正确的相册。 扫描这 100 个相册后,使用 album_id 键准确定位相关图片。 每个表都使用一个键来实现最佳性能,使查询速度比原来快 380 倍。
这并不意味着您应该在所有地方都添加索引,因为每个索引都会延长写入数据库的时间。 你在读取时获得优势,但在写入时失去优势。 因此,只添加实际提高读取性能的索引。 使用 EXPLAIN 确认并删除查询中未使用的任何索引。
有很多其他方法可以提高性能,您可以在我的 OSCON 演讲 Speed Up You Database 300 Times 中了解更多信息。
Anna 将在德克萨斯州奥斯汀的 OSCON 2017 上发表演讲 Speed Up You Database 300 Times。 如果您有兴趣参加会议,请使用此折扣码 在您注册时,为我们的读者:PCOS。
5 条评论