2011-11-18 108 views
0

我有一个缓慢(1.4秒)的查询,一直在困扰着我一段时间,所以我只是觉得我会把它,看看是否有人可以帮助我优化我的索引,加快它:优化mysql索引

select sql_calc_found_rows t.id, q.im_id, concat(t.si_id, ' ', t.de), q.date, q.das, q.dac, u.name, q.ac, q.st 
from t300q q 
left join t300 t on t.id = q.con_id 
left join users u on u.id = q.user_id 
order by q.date desc limit 0,100 

sql中解释结果:

SIMPLE q ALL  89126 Using filesort 
SIMPLE t eq_ref PRIMARY PRIMARY 4 db.q.con_id 1 
SIMPLE u eq_ref PRIMARY PRIMARY 4 db.q.user_id 1 

会话统计:

Handler_read_first = 0 
Handler_read_key = 177934 
Handler_read_next = 23 
Handler_read_prev = 679 
Handler_read_rnd = 15 
Handler_read_rnd_next = 89127 

,我有以下指标:

t.id - primary key 

q.con_id | 
q.date  | - all form a single index 
q.user_id | 

u.id - primary key 

,你可以看到从处理程序统计表q的大小为89126行。

这不是一个大问题,但如果可能的话,我希望速度低于1秒。

+0

'q.date '应该有索引? http://www.mysqlperformanceblog.com/2006/09/01/order-by-limit-performance-optimization/ – osgx

+0

完全不回答你的问题,但是你有选择在PostgreSQL下尝试相同的查询吗?我通常可以将10个表的连接数以百万计的行数减少到几百毫秒。在需要时自行组合索引是非常好的。 –

+0

不幸的是我没有postgresql – mulllhausen

回答

1

查询很慢,因为您没有日期索引。由于日期处于中间位置,因此无法使用复合索引。将日期移至现有索引中的第一个字段或创建独立索引。

+0

我试着将日期移动到索引中的第一个位置,但查询仍然需要1.4秒,然后我尝试为q.date本身添加一个新的索引(并且使其他索引与q .date,q.con_id,q.user_id),但查询仍需要大约1.4秒。感谢您的想法,尽管 – mulllhausen

+0

查询需要多长时间与解决问题无关。重要的是执行计划是否有任何改变。哪里? –

+0

好点。使用这三个关键定义中的任何一个都不会改变'explain select'输出。不过我只是尝试在另一个开发数据库上使用更高版本的MySQL完全相同的事情和查询在0.4秒内执行,所以它必须是... – mulllhausen

1

顺便说一句,mysql只对3列索引的前两列使用相等。最后一列可以使用范围查询。

即:

WHERE x=? AND y=? order by z; 

将使用的列的索引(X,Y,Z)(自Z可以是不等)。

尝试将'date'移动到第3列并重写查询。

如果这样做不起作用,那么mysql在智能上不足以处理连接中的con_id和user_id ..也许你可以重写它,以便这些连接条件在where子句中发生。

+0

好吧我试着恢复只包含以下字段的单个索引按照这个顺序:q.con_id,q.user_id,q.date,但速度仍然在1.4秒左右:P不知道要重新编写查询 - 我会保持这种最后的手段,因为它听起来像不好的SQL练习。无论如何感谢提示 – mulllhausen

0

尝试在数据库上触发OPTIMIZE或ANALYZE,但确保在只有少量请求的时间触发此操作,或者在服务器上没有请求正在执行时避免出现任何问题对出现的你可能会看到这个链接这个语句的更多信息:

http://dev.mysql.com/doc/refman/5.6/en/analyze-table.html http://dev.mysql.com/doc/refman/4.1/en/optimize-table.html