2

我有下面的代码,当表中只有几个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 事件 ALL NULL NULL NULL NULL 1593 使用 where;使用临时的;使用文件排序    
1 个简单的 tblfollowers 参考 PRIMARY PRIMARY   
4 dbhappps.events.id_user 17 使用where;使用索引     

这是表格

块引用

表事件:

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

块引用

关注者:

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

如何加快此查询速度?

4

4 回答 4

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来告知您的决策,添加索引会减慢您的插入和更新速度,并使您的磁盘使用量膨胀。

于 2013-10-09T00:41:50.800 回答
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'
于 2013-10-16T22:09:00.970 回答
1

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

什么时候使用临时表?MySQL 参考手册 - 优化数据库结构中对此进行了很好的描述。在您的情况下,它必须发生,因为您按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')

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

于 2013-10-14T20:11:47.000 回答
0

没有 create table 语句就很难说。

对于该 group by 和 order by。如果 event_id 不是主要的,您可能会通过在 event_id、时间戳 desc 上添加复合索引来看到一些改进。如果按 event_id 排序,时间戳 desc 是可以接受的,这样可以节省一些时间。Group 执行隐式排序,因此重新排序会减慢速度。按 event_id、时间戳 ASC 分组,然后按时间戳 DESC 排序可能会接近该排序的最坏情况。

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

于 2013-10-16T14:01:10.190 回答