我目前创建了一个类似于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条MAX记录,您会采取哪种方法?临时表,视图还是php?
答案 0 :(得分:5)
一些想法:
临时表: 临时表只会在会话处于活动状态时持续。如果在PHP脚本中运行代码,则在脚本完成执行时将自动销毁临时表。
<强>视图强>: 这些主要用于隐藏复杂性,因为您使用连接创建它,然后像单个表一样访问它。下划线代码是SELECT语句。
PHP数组: 比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将我的值放入使用PHP的数组中。这仍然会使最初的繁重工作留给数据库引擎,并使您无法多次调用数据库服务器。
答案 1 :(得分:1)
试试这个:
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结果。这一切都可以在flash中完成,使用join语句可以显着缩短整体查询时间。
答案 2 :(得分:0)
问题是您正在使用相关子查询。我想你的查询需要一段时间才能运行,如果它不在查询缓存中?这就是导致你的表锁定并导致争用的原因。
将表格类型切换为InnoDB会有所帮助,但您的核心问题是您的查询。
150到200个记录非常多。 MySQL确实支持存储过程,但这不是你需要它的东西。插入不是资源密集型的,但是很多一次插入或按顺序插入(使用批量插入语法)会导致问题。