我有以下问题:
有2个MySQL数据库Database_1是原始数据库和Database_2,它基于第一个数据库,只有很少的变化(一些新的列,不同的数据)。
当我运行一个涉及数据库中3个表的查询时,我会得到非常不同的性能结果。我在同一个localhost服务器上测试两个数据库。
查询:
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秒 - 这个数据库虽然比较大,却是较大的数据库 更快
Database_2 - 1分40秒
所有3个表都使用MyISAM引擎。表申请人和项目有charset utf8,表authake_users有charset latin1。
我检查了索引(两个数据库都有完全相同的索引),重建它们并在所有3个表上使用ANALYZE和OPTIMIZE但没有成功。
我发现的唯一区别是显示如下,当我在前面使用EXPLAIN命令运行查询时:
有人知道该找什么吗?什么可以导致性能上的这种差异?
答案 0 :(得分: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
个查询,我会非常感兴趣。