mysql慢查询问题
Posted
技术标签:
【中文标题】mysql慢查询问题【英文标题】:mysql Slow query issue 【发布时间】:2017-02-01 09:51:55 【问题描述】:我有以下问题:
有 2 个 mysql 数据库 Database_1 是原始数据库,Database_2 基于第一个数据库,只有很少的更改(一些新列,不同的数据)。
当我运行一个涉及数据库中 3 个表的查询时,我得到了非常不同的性能结果。我在同一个本地主机服务器上测试两个数据库。
查询:
SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id
FROM `applicants` AS `Applicant`
LEFT JOIN `authake_users` AS `User` ON (`Applicant`.`authake_user_id` = `User`.`id`)
LEFT JOIN `projects` AS `Project` ON (`Project`.`applicant_id` = `Applicant`.`id`)
WHERE `User`.`login` LIKE _latin1 '%1000%' AND `Project`.`id` IS NULL;
查询执行时间:
Database_1 – 0.3 s – 这个数据库是更大的,虽然它是 更快
Database_2 – 1 分 40 秒
所有 3 个表都使用 MyISAM 引擎。表申请者和项目的字符集为 utf8,表 authake_users 的字符集为 latin1。
我检查了索引(两个数据库的索引完全相同),重建它们并在所有 3 个表上使用了 ANALYZE 和 OPTIMIZE,但没有成功。
我发现的唯一区别如下所示,当我在前面使用 EXPLAIN 命令运行查询时:
数据库_1
数据库_2
有人知道要寻找什么吗?是什么导致了这种性能差异?
【问题讨论】:
检查索引,可能因记录数量而异。 您有机会在下面查看我的答案吗?请试用并更新。 【参考方案1】:请记住,MySql 查询分析器根据可用资源内存选择优化计划。但是改变表的顺序和他们的 JOIN 计划确实有助于它选择一个更好的计划。
我无权访问数据库,而且我不知道您需要从此查询中获得的输出,这就是为什么无法执行分析的原因。但以下是一些您可以尝试的建议
您的查询没有WHERE
SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id
FROM `applicants` AS `Applicant`
LEFT JOIN `authake_users` AS `User`
ON `Applicant`.`authake_user_id` = `User`.`id`
AND `User`.`login` LIKE _latin1 '%1000%'
LEFT JOIN `projects` AS `Project`
ON `Project`.`applicant_id` = `Applicant`.`id`
AND `Project`.`id` IS NULL;
通过更改JOINS
的顺序和没有WHERE
SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id
FROM `authake_users` AS `User`
LEFT JOIN `applicants` AS `Applicant`
ON `Applicant`.`authake_user_id` = `User`.`id`
AND `User`.`login` LIKE _latin1 '%1000%'
LEFT JOIN `projects` AS `Project`
ON `Project`.`applicant_id` = `Applicant`.`id`
AND `Project`.`id` IS NULL;
您的查询通过更改JOINS
- 1 的顺序进行
SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id
FROM `authake_users` AS `User`
LEFT JOIN `applicants` AS `Applicant`
ON `Applicant`.`authake_user_id` = `User`.`id`
LEFT JOIN `projects` AS `Project`
ON `Project`.`applicant_id` = `Applicant`.`id`
WHERE `User`.`login` LIKE _latin1 '%1000%' AND `Project`.`id` IS NULL;
您通过更改JOINS
- 2 的顺序查询
SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id
FROM `projects` AS `Project`
LEFT JOIN `applicants` AS `Applicant`
ON `Project`.`applicant_id` = `Applicant`.`id`
LEFT JOIN `authake_users` AS `User`
ON `Applicant`.`authake_user_id` = `User`.`id`
WHERE `User`.`login` LIKE _latin1 '%1000%' AND `Project`.`id` IS NULL;
另外,如果您想充分利用索引,则应避免此类User.login LIKE _latin1 '%1000%'
条件。如果你真的需要,最好使用这样的东西User.login LIKE _latin1 '1000%'
。
如果您也可以发布我建议的查询的EXPLAIN
,我会非常感兴趣。
【讨论】:
谢谢,真的是“改变JOINS的顺序-1”的解决方案大大加快了查询速度 酷!如果您也可以分享他们的EXPLAIN
详细信息,那就更好了:)以上是关于mysql慢查询问题的主要内容,如果未能解决你的问题,请参考以下文章