当前位置: 首页 > 图文教程 > 网络编程 > PHP > 通过缓存数据库结果提高PHP性能(3)

PHP
PHP 变量类型的强制转换
PHP 判断变量类型实现代码
PHP 数组教程 定义数组
php后台程序与Javascript的两种交互方式
php 文件上传系统手记
php 网页游戏开发入门教程一(webgame+design)
PHP 简单日历实现代码
dedecms 批量提取第一张图片最为缩略图的代码(文章+软件)
php 显示指定路径下的图片
php pack与unpack 摸板字符字符含义
ThinkPHP php 框架学习笔记
PHP 批量删除数据的方法分析
PHP 读取和修改大文件的某行内容的代码
php实现jQuery扩展函数
浅谈PHP 闭包特性在实际应用中的问题
PHP 文件上传源码分析(RFC1867)
php 攻击方法之谈php+mysql注射语句构造
PHP+MySQL 手工注入语句大全 推荐
php UTF8 文件的签名问题
php 远程包含文件漏洞分析

通过缓存数据库结果提高PHP性能(3)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-03   浏览: 42 ::
收藏到网摘: n/a

将表添加到现有注册

  前一部分介绍了如何使用更改通知服务使数据库在注册对象(在以上示例中为 ORDERS 表)发生更改时发出通知。但从性能角度而言,客户端应用程序可能更希望缓存 ORDER_ITEMS 表而非 ORDERS 表本身的查询结果集,这是因为它在每次访问订单时,不得不从 ORDERS 表中只检索一行,但同时必须从 ORDER_ITEMS 表中检索多个行。在实际情况中,订单可能包含数十个甚至数百个订单项。

  由于您已经对 ORDERS 表注册了查询,因此不必再创建一个注册来注册对 ORDER_ITEMS 表的查询了。相反,您可以使用现有注册。为此,您首先需要检索现有注册的 ID。可以执行以下查询来完成此工作

SELECT regid, table_name FROM user_change_notification_regs;
  结果可能如下所示:
REGID TABLE_NAME 
----- --------------
241 OE.ORDERS
  获取注册 ID 后,可以使用 DBMS_CHANGE_NOTIFICATION.ENABLE_REG 函数将一个新对象添加到该注册,如下所示:
DECLARE 
ord_id NUMBER;
BEGIN
DBMS_CHANGE_NOTIFICATION.ENABLE_REG(241);
SELECT order_id INTO ord_id FROM order_items WHERE ROWNUM < 2;
DBMS_CHANGE_NOTIFICATION.REG_END;
END;
/
  完成了!从现在开始,数据库将生成一个通知来响应对 ORDERS 和 ORDER_ITEMS 所做的任何更改,并调用 orders_nf_callback 过程来处理通知。因此,下一步就是编辑 orders_nf_callback,以便它可以处理因对 ORDER_ITEMS 表执行 DML 操作而生成的通知。但在重新创建 orders_nf_callback 过程之前,您需要创建以下将在更新过程中引用的表类型:
CREATE TYPE rdesc_tab AS TABLE OF SYS.CHNF$_RDESC;
  然后,返回清单 2,在以下代码行之后:
IF (tblname = 'OE.ORDERS') THEN 
FOR j IN 1..numrows LOOP
row_id := ntfnds.table_desc_array(i).row_desc_array(j).row_id;
SELECT order_id INTO ord_id FROM orders WHERE rowid = row_id;
sendNotification(url, tblname, ord_id);
END LOOP;
END IF;
  插入以下代码:
IF (tblname = 'OE.ORDER_ITEMS') THEN 
FOR rec IN (SELECT DISTINCT(o.order_id) o_id FROM
TABLE(CAST(ntfnds.table_desc_array(i).row_desc_array AS rdesc_tab)) t,
orders o, order_items d WHERE t.row_id = d.rowid AND d.order_id=o.order_id)
LOOP
sendNotification(url, tblname, rec.o_id);
END LOOP;
END IF;
  重新创建 orders_nf_callback 后,您需要测试它能否正常工作。为此,您可以针对 ORDER_ITEMS 表执行下列 UPDATE 语句并提交该事务:
UPDATE ORDER_ITEMS SET quantity = 160 WHERE order_id=2421 AND line_item_id=1; 
UPDATE ORDER_ITEMS SET quantity = 160 WHERE order_id=2421 AND line_item_id=2;
COMMIT;
  然后,检查 nfresults 表,如下所示:
SELECT TO_CHAR(operdate, 'dd-mon-yy hh:mi:ss') operdate, 
rslt_msg FROM nfresults WHERE tblname = 'OE.ORDER_ITEMS';
  输出可能如下所示:
OPERDATE RSLT_MSG 
------------------- --------------
03-mar-06 12:32:27 Not Found
  您可能很奇怪为什么只向 nfresults 表中插入了一行 – 毕竟您更新了 ORDER_ITEMS 表中的两行。实际上,这两个更新了的行具有相同的 order_id – 即它们属于同一订单。此处,我们假设客户端应用程序将使用一个语句选择订单的所有订单项,因此它并不需要确切知道已经更改了某个订单的哪些订单项。相反,客户端需要知道其中至少修改、删除或插入了一个订单项的订单 ID。