我目前已经创建了一个类似facebook的页面,从不同的表格中拉出通知,让我们说大约8个表格。每个表都有不同的结构,具有不同的列,所以首先想到的是我将有一个全局表,就像目录一样,并在每次新的命中时刷新它。我知道插入是资源密集型的,但我希望因为它是一个静态表,所以我希望每100个访问者中可能只添加一个新记录,所以我想“也许”我可以逃脱这个责任,但我错了。只有三个人对网站进行了猛烈攻击,我成功地解决了这些问题。
所以不管怎样,现在我必须用一种不同的方法来重做。最初我打算做视图,但我对视图有一个问题。所选表必须包含用户的id。下面是一个来自php的select语句示例:
$get_events = "
SELECT id, " . $userId . ", 'admin_events', 0, event_start_time
FROM admin_events
WHERE CURDATE() < event_start_time AND
NOT EXISTS(SELECT id
FROM admin_event_registrations
WHERE user_id = " . $userId . " AND admin_events.id = event_id) AND
NOT EXISTS(SELECT id
FROM admin_event_declines
WHERE user_id = " . $userId . " AND admin_events.id = event_id) AND
event_capacity > (SELECT COUNT(*) FROM admin_event_registrations WHERE event_id = admin_events.id)
LIMIT 1抱歉,弄得乱七八糟。正如您所看到的,在任何情况下,我都需要将页面中的用户Id作为表中选定的列返回。我不知道如何使用视图,所以我不认为视图是我的方向,因为这样的查询类型要多得多。我有MSSQL背景,我喜欢存储过程,所以如果有MYSQL的存储过程,那就太好了。
接下来,我开始考虑临时表。表将在内存中,表可能最多150行,并且不会有死锁。在临时表上执行插入操作仍然非常昂贵吗?我最终会使服务器崩溃吗?现在我们每天大概有100个用户,但是当我们有更多的用户时,我想试着成为未来的证明。
经过长时间的思考,我认为唯一的方法是用户php并以数组的形式获得所有结果。问题是我会得到类似这样的东西:
$my_array[0]["date_created"] = <current_date>上面的问题是我必须按date_created排序,但这是一个多维数组。
无论如何,要从数据库中提取最多150到200条记录,您会采用哪种方法?临时表、视图还是php?
发布于 2010-09-17 02:23:21
一些想法:
Temp Tables:临时表仅在会话处于活动状态时有效。如果您在PHP脚本中运行代码,那么当脚本执行完毕时,临时表将自动销毁。
视图:它们主要用于隐藏复杂性,因为您可以使用连接创建它,然后像访问单个表一样访问它。加下划线的代码是SELECT语句。
SQL数组:从其中获取数据比更麻烦。然而,PHP确实有一些功能可以使工作变得更容易,但没有真正的查询语言。
存储过程:MySQL中有存储过程-请参阅:http://dev.mysql.com/doc/refman/5.0/en/stored-routines-syntax.html
我的建议:首先,使用MySQL查询分析器重写查询:http://www.mysql.com/products/enterprise/query.html
现在我将使用PDO将我的值放入一个数组中。这仍然会将最初的繁重工作留给DB引擎,并阻止您对DB服务器进行多次调用。
发布于 2010-09-17 03:01:03
试试这个:
SELECT id, " . $userId . ", 'admin_events', 0, event_start_time
FROM admin_events AS ae
LEFT JOIN admin_event_registrations AS aer
ON ae.id = aer.event_id
LEFT JOIN admin_event_declines AS aed
ON ae.id = aed.event_id
WHERE aed.user_id = ". $userid ."
AND aer.user_id = ". $userid ."
AND aed.id IS NULL
AND aer.id IS NULL
AND CURDATE() < ae.event_start_time
AND ae.event_capacity > (
SELECT SUM(IF(aer2.event_id IS NOT NULL, 1, 0))
FROM admin_event_registrations aer2
JOIN admin_events AS ae2
ON aer2.event_id = ae2.id
WHERE aer2.user_id = ". $userid .")
LIMIT 1它仍然有一个子查询,但您会发现它比给出的其他选项要快得多。MySQL可以很容易地连接表(尽管它们都应该是相同的表类型)。此外,最后一条count语句不会以null结果的方式响应,除非您处理NULL值。这一切都可以在瞬间完成,并且使用join语句可以显著减少总体查询时间。
发布于 2010-09-17 02:16:33
问题是您使用的是相关子查询。如果您的查询不在查询缓存中,我想您的查询需要一些时间才能运行?这就是导致表锁定和争用的原因。
将表类型切换为InnoDB会有所帮助,但您的核心问题是查询。
150到200条记录是一个很大的数字。MySQL确实支持存储过程,但这不是您需要它的目的。插入不会占用大量资源,但一次插入或按顺序插入(使用bulk insert语法)可能会导致问题。
https://stackoverflow.com/questions/3728963
复制相似问题