MySql查询优化:按在线成员排序

时间:2012-12-06 08:33:49

标签: php mysql

我有以下查询,工作正常:

SELECT
    a.i_am,a.seeking_a,
    a.zodiac,
    a.my_marital_status,
    a.city,a.country,
    a.my_age,
    a.intrested_in1,
    a.intrested_in2,
    a.intrested_in3,
    a.intrested_in4,
    a.intrested_in5,
    a.intrested_in6,
    a.user_id,
    a.picture_type,
    a.photo,
    a.block_photo,
    r.username,
    u.title,
    u.about_myself
FROM ".TBL_ABOUT_MYSELF." a 
INNER JOIN ".TBLREGISTRATION."  r ON a.user_id=r.ID 
INNER JOIN ".TBLUSERDETAILS." u ON a.user_id=u.user_id 
LEFT JOIN ".TBLSTEPS." s ON a.user_id=s.user_id 
WHERE 1 $condition $gender_condition 
ORDER BY a.user_id 
DESC LIMIT $from,10

需要 0.5秒才能获取结果。 总共有1,000,000个结果。

现在,如果我再加入一个表(用户在线状态:

SELECT
    a.i_am,a.seeking_a,
    a.zodiac,
    a.my_marital_status,
    a.city,a.country,
    a.my_age,
    a.intrested_in1,
    a.intrested_in2,
    a.intrested_in3,
    a.intrested_in4,
    a.intrested_in5,
    a.intrested_in6,
    a.user_id,
    a.picture_type,
    a.photo,
    a.block_photo,
    r.username,
    u.title,
    u.about_myself
FROM ".TBL_ABOUT_MYSELF." a
INNER JOIN ".TBLREGISTRATION."  r ON a.user_id=r.ID 
INNER JOIN ".TBLUSERDETAILS." u ON a.user_id=u.user_id 
LEFT JOIN ".TBLSTEPS." s ON a.user_id=s.user_id
LEFT JOIN ".TBL_USER_ONLINE." ON a.user_id=o.user_id  <-- New Line
WHERE 1 $condition $gender_condition
ORDER BY o.user_id DESC, a.user_id DESC LIMIT $from,10  <-- One more order by

现在需要 12秒才能获取结果。

如何优化此功能?

mysql查询说明:

SQL result

Host: localhost
Database: mysite_new
Generation Time: Dec 06, 2012 at 09:09 AM
Generated by: phpMyAdmin 3.2.0.1 / MySQL 5.1.36-community-log
SQL query: EXPLAIN SELECT a.i_am,a.seeking_a,a.zodiac,a.my_marital_status,a.city,a.country,a.my_age,a.intrested_in1,a.intrested_in2,a.intrested_in3,a.intrested_in4,a.intrested_in5,a.intrested_in6,a.user_id,a.picture_type,a.photo,a.block_photo,r.username,u.title, u.about_myself ,o.user_id as online_user_id FROM mysite_about_myself_new a INNER JOIN mysite_user_registration_new r ON a.user_id=r.ID INNER JOIN mysite_user_details_new u ON a.user_id=u.user_id LEFT JOIN mysite_steps_new s ON a.user_id=s.user_id LEFT JOIN mysite_usersonline_new o ON a.user_id=o.user_id WHERE 1 and r.block_by_webmaster='0' and a.approved='1' and s.step1='1' AND a.i_am ='2' AND a.seeking_a = '1' ORDER BY o.user_id DESC LIMIT 0,10; 
Rows: 5

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  a   ref user_id,i_am    i_am    2   const   30011   Using where; Using temporary; Using filesort
1   SIMPLE  o   ref user_id user_id 4   mysite_new.a.user_id    2   Using index
1   SIMPLE  s   eq_ref  user_id user_id 4   mysite_new.a.user_id    1   Using where
1   SIMPLE  u   eq_ref  user_id user_id 4   mysite_new.s.user_id    1   Using where
1   SIMPLE  r   eq_ref  PRIMARY PRIMARY 4   mysite_new.u.user_id    1   Using where

第二次解释为:

SQL result

Host: localhost
Database: mysite_new
Generation Time: Dec 06, 2012 at 10:02 AM
Generated by: phpMyAdmin 3.2.0.1 / MySQL 5.1.36-community-log
SQL query: EXPLAIN SELECT a.i_am,a.seeking_a,a.zodiac,a.my_marital_status,a.city,a.country,a.my_age,a.intrested_in1,a.intrested_in2,a.intrested_in3,a.intrested_in4,a.intrested_in5,a.intrested_in6,a.user_id,a.picture_type,a.photo,a.block_photo,r.username,u.title, u.about_myself ,o.user_id as online_user_id FROM mysite_about_myself_new a INNER JOIN mysite_user_registration_new r ON a.user_id=r.ID INNER JOIN mysite_user_details_new u ON a.user_id=u.user_id LEFT JOIN mysite_steps_new s ON a.user_id=s.user_id LEFT JOIN mysite_usersonline_new o ON a.user_id=o.user_id WHERE 1 and r.block_by_webmaster='0' and a.approved='1' and s.step1='1' AND a.i_am ='2' AND a.seeking_a = '1' ORDER BY a.user_id DESC LIMIT 0,10; 
Rows: 5

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  a   index   user_id,i_am    user_id 4   NULL    38  Using where
1   SIMPLE  o   ref user_id user_id 4   mysite_new.a.user_id    2   Using index
1   SIMPLE  s   eq_ref  user_id user_id 4   mysite_new.a.user_id    1   Using where
1   SIMPLE  u   eq_ref  user_id user_id 4   mysite_new.s.user_id    1   Using where
1   SIMPLE  r   eq_ref  PRIMARY PRIMARY 4   mysite_new.u.user_id    1   Using where

3 个答案:

答案 0 :(得分:0)

将此新行更改为

    LEFT JOIN ".TBL_USER_ONLINE." o  on ON a.user_id=o.user_id

编辑: 然后你的问题是ORDER BY。 您的查询需要很长时间才能对两个表中的两个user_id进行排序,请尝试使用一个user_id 从一张桌子

EDIT2:

将此o.user_id也添加到SELECT部分 像那样

 SELECT
a.i_am,a.seeking_a,
a.zodiac,
a.my_marital_status,
a.city,a.country,
a.my_age,
a.intrested_in1,
a.intrested_in2,
a.intrested_in3,
a.intrested_in4,
a.intrested_in5,
a.intrested_in6,
a.user_id,
a.picture_type,
a.photo,
a.block_photo,
r.username,
u.title,
u.about_myself
o.user_id                 <-- New Line

答案 1 :(得分:0)

问题很可能在排序中。在第一个查询中,MySQL可以使用a.user_id索引进行排序,而在第二个查询中,它必须执行一百万条记录的filesort,以便对两个表的列进行排序(然后寻找一些指向结果集中的LIMIT子句。

o.user_id排序应该足够了,因为它是NULL或等于a.user_id

此外,如果您能够使用o.user_id条款中的WHERE上的不等式限制查询,则至少不需要寻找到目前为止。

答案 2 :(得分:0)

为什么在两列上使用order by

ORDER BY o.user_id DESC, a.user_id DESC

我认为o.user_id和a.user_id对于单个用户来说将是相同的值,因此您只需使用一个。

o.user_id如果要按顺序从表TBL_USER_ONLINE中包含null a.user_id如果您只想对用户ID进行订购。

同样使用EXPLAIN并为连接创建任何必要的索引,其中条件和按列排序