MySql临时表VS视图VS php数组

时间:2010-09-16 17:02:00

标签: php mysql

我目前创建了一个类似于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?

3 个答案:

答案 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确实支持存储过程,但这不是你需要它的东西。插入不是资源密集型的,但是很多一次插入或按顺序插入(使用批量插入语法)会导致问题。