优化大型MySQL查询

时间:2013-05-31 09:19:07

标签: mysql optimization

今天我的托管服务提供商告诉我,我的数据库必须立即被阻止。我有一个查询导致服务器上的巨大负载。您知道如何优化我的查询只是为了减少服务器负载吗?

SELECT `users`.`id`,
       `why_me`, 
       `created`,
       `thumbnail`,
       `rating_date`,
       CONCAT(first_name, ' ', last_name) AS name,
       SUBSTRING(why_me, 1, 27) as subwhy,
       COUNT(`rating_date`) AS total,
       MAX(`rating_date`) AS maxrate
  FROM (`user_profiles`)
  LEFT OUTER JOIN `rates` ON `user_profiles`.`id`=`rates`.`user_id`
  JOIN `users` ON `user_profiles`.`user_id`=`users`.`id`
  WHERE `users`.`activated` =  '1'
      AND `last_name` != ""
      AND `first_name` != ""
      AND  concat_ws(' ', first_name, last_name) COLLATE UTF8_GENERAL_CI  LIKE '%%'
  GROUP BY `user_profiles`.`user_id`
  ORDER BY `total` desc

我很感激你的任何帮助。谢谢!

1 个答案:

答案 0 :(得分:1)

AND  concat_ws(' ', first_name, last_name) COLLATE UTF8_GENERAL_CI  LIKE '%%'

没有效果,但价格昂贵(长时间运行)。它会逐个扫描所有行,而不会返回任何有用的内容。除去!

登录phpmyadmin并运行此查询,前缀为“ EXPLAIN ”,即“EXPLAIN SELECT users ...”。 发布结果。它将向我们展示SQL是否可以直接寻址所需的行,或者它是否可以逐个搜索它们。注意行使用的键:如果它是空的,则需要additioanl indeces:

1)确保每个用于连接的列都有索引,即rates.user_id和user_profiles.user_id。

2)确保您对用于具有高基数的where部分的所有内容都有权限,即first_name和last_name。

3)更好:创建索引超过3列:activated,first_name,last_name

4)GROUP和ORDER BY导致临时表的构建。你能把这个逻辑中的一些移植到PHP中吗?

5)缓存结果。没有什么可以实时完成的!