我刚刚下载了我的慢查询日志 并且经常显示的一个查询是
select * from feedback_to_user
left join user_tb on feedback_to_user.feedbacker_id = user_tb.user_id
left join user_to_photo on feedback_to_user.feedbacker_id = user_to_photo.user_id
where feedback_to_user.feedbackee_id="7375"
AND user_tb.admin_review = "1"
AND user_tb.user_published = "1"
AND user_tb.user_active = "1"
AND user_tb.user_verified = "1"
order by feedback_to_user.ftu_id DESC;
所以我该如何解决?语法还是phpmyadmin?
答案 0 :(得分:1)
正如帕特里克已经建议的那样,你应该使用EXPLAIN。
但一般来说,您应该考虑这些要点(在查询检查顺序中):
从feedback_to_user选择* ...
是否真的有必要选择带有星号的所有字段?也许您只需要几个。让巨大的数据块肆无忌惮地被忽略和/或丢弃,这一点毫无意义;最好不要在第一时间选择它们。此外,这样MySQL将更好地估计实际的检索成本,并且可能更好地优化查询(稍后参见覆盖索引)。
在feedback_to_user.feedbacker_id = user_tb.user_id
上左连接user_tb
你是否希望不能成为feedbacker_id中的任何用户,以便该行将所有user_tb字段设置为NULL,并且您是否还需要该行?如果不是,则使用直接JOIN(不是LEFT JOIN)。改进可能是微不足道的 - 但它们仍然是免费的(出于同样的原因,如果您有疑问,那么请留下LEFT JOIN)。
在feedback_to_user.feedbacker_id = user_to_photo.user_id
上左加入user_to_photo
与上述相同。你只需要带的照片吗?如果是这样,请加入。
其中feedback_to_user.feedbackee_id =" 7375"
AND user_tb.admin_review =" 1"
AND user_tb.user_published =" 1"
AND user_tb.user_active =" 1"
AND user_tb.user_verified =" 1"
所有这些字段 VARCHAR 还是整数?如果只在那里存储整数(偶尔会出现NULL),那么拥有一个整数数据字段会产生很好的红利。如果你将它们用作旗帜,那么TINYINT可能(并且可能不会)进一步提高性能。也可以调查位域。
但是,如果您有很多这些问题,那么您可以使用您要查询的字段在user_tb
上创建一个INDEX:
CREATE INDEX user_db_flags
ON user_tb(admin_review,
user_published,
user_active,
user_verified);
您可以尝试添加您在JOIN中使用的user_id
字段:
-- remove previous index
ALTER TABLE user_tb DROP INDEX user_db_flags;
-- add index
CREATE INDEX user_db_flags
ON user_tb(user_id,
admin_review,
user_published,
user_active,
user_verified);
有关feedback_to_user的指数:
CREATE INDEX feedback_to_user_id
ON feedback_to_user(feedbacker_id, feedbackee_id, ftu_id);
您也可以尝试交换这些职位:
CREATE INDEX feedback_to_user_id
ON feedback_to_user(feedbackee_id, feedbacker_id, ftu_id);
这将有助于MySQL摆脱冗余信息并快速找到您需要的信息。
如果其中一个JOINed表只有非常少的非常小的字段,并且选择非常精确(例如feedback_to_user就是你选择单个feedbackee_id的情况),你可以使用&#34 ;覆盖索引",即包含您在第一个位置搜索的字段的索引,以及您在下一个位置需要的字段。特别是如果表有许多其他更大的字段,这允许MySQL在索引上查询而根本不加载表。如果索引足够小于表,则速度增益可能很大。否则,不要打扰 - 维护索引也会产生费用。
答案 1 :(得分:0)
请使用EXPLAIN
进行分析,请参阅:
http://dev.mysql.com/doc/refman/5.7/en/using-explain.html
不幸的是我们不知道你的表格结构的行数和索引,但你应该从优化开始阅读:
http://dev.mysql.com/doc/refman/5.7/en/select-optimization.html