我有以下代码,当表格follower_id
中只有少数username
或tblfollowers
时,它会正常加载。
但是一旦它进入成千上万,它的加载速度非常慢
有没有更好的方法来写这个?
我在它加入的字段上添加了索引,这似乎没有什么区别。
$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
如何加快查询速度?
答案 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的复合索引。