mysql慢查询问题

时间:2017-02-01 09:51:55

标签: mysql database

我有以下问题:

有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命令运行查询时:

Database_1 enter image description here

了Database_2 enter image description here

有人知道该找什么吗?什么可以导致性能上的这种差异?

1 个答案:

答案 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;

更改JOINSWHERE

的顺序
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个查询,我会非常感兴趣。