SQL加载时间慢

时间:2013-10-09 00:31:02

标签: php mysql sql

我有以下代码,当表格follower_id中只有少数usernametblfollowers时,它会正常加载。
但是一旦它进入成千上万,它的加载速度非常慢 有没有更好的方法来写这个?

我在它加入的字段上添加了索引,这似乎没有什么区别。

$scheduler->render_table("events 
    LEFT JOIN tblfollowers ON events.id_user = tblfollowers.username 
    WHERE events.status ='active' 
      AND((tblfollowers.follower_id)='$test') OR ((events.id_user) ='$test') 
    GROUP BY events.event_id, events.event_name, events.user_name, events.id_user, events.time, events.details, events.location, events.dresscode 
    ORDER BY events.timestamp DESC"
  ,"event_id","start_date, start_date,event_name,details");
$scheduler->render_sql("SELECT event_id, start_date, end_date, event_name, details 
                        FROM events ");

以下是此查询的说明:

1 SIMPLE events ALL NULL NULL NULL NULL 1593 Using where; Using temporary; Using filesort    
1 SIMPLE tblfollowers ref PRIMARY PRIMARY   
4 dbhappps.events.id_user 17 Using where; Using index     

以下是表格

  

块引用

表格事件:

event_id   int(11)  Primary Unique Index    
event_name varchar(400) 
user_name  varchar(155)  
id_user int(11)  Primary Unique  Index
start_date datetime
end_date  datetime   
details varchar(700)
location varchar(255)
dresscode varchar(255)
timestamp timestamp on update CURRENT_TIMESTAMP
  

Blockquote

tblfollowers:

username int(11) primary
follower_id int(11) primary
timestamp timestamp on update CURRENT_TIMESTAMP

如何加快查询速度?

4 个答案:

答案 0 :(得分:2)

group by只需要两个字段(如果字段event_id是主键,则只需要 字段。
分组考虑较少的字段应该可以使您的查询更快 您应该只将功能独立的字段放在组中,列出功能相关的字段,这是非荒谬的,浪费时间。
幸运的是,MySQL并不要求你这样做。

$scheduler->render_table("events  
   LEFT JOIN tblfollowers ON events.id_user = tblfollowers.username 
   WHERE events.status ='active' 
     AND '$test' IN (tblfollowers.follower_id, events.id_user) <<-- maybe faster
   GROUP BY events.event_id, events.id_user   <<-- only include unique key fields
   ORDER BY events.timestamp DESC"
,"event_id","start_date, start_date,event_name,details");
$scheduler->render_sql("SELECT event_id, start_date, end_date, event_name, details 
                        FROM events ");

有关详细信息,请参阅此处:http://rpbouman.blogspot.com/2007/05/debunking-group-by-myths.html

为什么会慢?
没有tblfollowers和事件的表定义,很难说。

使用说明
如果您想查看瓶颈的位置,请在选择前放置EXPLAIN并在结果中粘贴结果。

$scheduler->render_sql("EXPLAIN SELECT event_id, start_date, end_date, event_name, details 
                        FROM events ");

解决索引无济于事
使用explain的输出来通知您的决策,添加索引会减慢插入和更新速度,并增加磁盘使用率。

答案 1 :(得分:1)

这主要是一个减慢查询速度的临时文件。 temporary中的单词EXPLAIN表示每次运行此查询时,MySQL服务器都必须创建一个临时表。虽然它很小,但它保存在内存中,因此速度相对较快。当它变得足够大时,它会被移动到磁盘并使查询运行得非常慢。

什么时候使用临时表?它在MySQL Reference Manual – Optimizing Database Structure中有详细描述。在您的情况下,它必须发生,因为您按字段timestamp排序,而GROUP BY子句中未包含该字段。

接下来,您真的需要按所有这些字段进行分组吗?由于您按events表的主键进行分组,因此按另一个event字段进行分组是没有意义的。尝试执行此查询:

$scheduler->render_table("events 
    LEFT JOIN tblfollowers ON events.id_user = tblfollowers.username 
    WHERE events.status = 'active' 
    AND tblfollowers.follower_id = '$test'
    OR events.id_user = '$test'
    GROUP BY events.event_id, events.timestamp 
    ORDER BY events.timestamp DESC"
, "event_id", "start_date, start_date, event_name, details");

编辑:顺便问一下,你不忘记把括号括在条件之外吗? AND优先于OR

WHERE events.status ='active' 
      AND (tblfollowers.follower_id='$test' OR events.id_user='$test')

这样对我来说似乎更合乎逻辑。

答案 2 :(得分:1)

完全透露:我不懂PHP。

但是,请尝试拆分查询并使用UNION将其重新组合在一起。我认为这是OR通过阻止使用你的索引来扼杀你的表现。这就是我认为您的查询在PHP之外的样子。

SELECT event_id
     , start_date
     , end_date
     , event_name
     , details 
  FROM events
  LEFT JOIN tblfollowers 
    ON events.id_user = tblfollowers.username 
 WHERE events.status ='active' 
   AND tblfollowers.follower_id = '$test'
UNION
SELECT event_id
     , start_date
     , end_date
     , event_name
     , details 
  FROM events
 WHERE id_user = '$test'

答案 3 :(得分:0)

没有create table语句很难说。

对于该组和按顺序排列。 如果event_id不是主要的,您可以通过在event_id,timestamp desc上添加复合索引来看到一些改进。如果按event_id排序,则可以接受时间戳desc,这将节省您一些时间。由于重新排序会使事情变慢,因此集团会执行隐含的订单。按event_id进行分组,时间戳ASC然后按时间戳DESC排序可能接近该排序的最坏情况。

如果event_id是主要的,则在时间戳DESC上添加索引将创建event_id和timstamp DESC的复合索引。