今天我的托管服务提供商告诉我,我的数据库必须立即被阻止。我有一个查询导致服务器上的巨大负载。您知道如何优化我的查询只是为了减少服务器负载吗?
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
我很感激你的任何帮助。谢谢!
答案 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)缓存结果。没有什么可以实时完成的!