知识大全 通过缓存数据库结果提高PHP性能
Posted 知
篇首语:怀抱观古今,寝食展戏谑。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 通过缓存数据库结果提高PHP性能相关的知识,希望对你有一定的参考价值。
通过缓存数据库结果提高PHP性能 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
众所周知 缓存数据库查询的结果可以显著缩短脚本执行时间 并最大限度地减少数据库服务器上的负载 如果要处理的数据基本上是静态的 则该技术将非常有效 这是因为对远程数据库的许多数据请求最终可以从本地缓存得到满足 从而不必连接到数据库 执行查询以及获取结果
但当您使用的数据库与 Web 服务器位于不同的计算机上时 缓存数据库结果集通常是一个不错的方法 不过 根据您的情况确定最佳的缓存策略却是一个难题 例如 对于使用最新数据库结果集比较重要的应用程序而言 时间触发的缓存方法(缓存系统常用的方法 它假设每次到达失效时间戳记时就重新生成缓存)可能并不是一个令人满意的解决方案 这种情况下 您需要采用一种机制 每当应用程序需要缓存的数据库数据发生更改时 该机制将通知该应用程序 以便该应用程序将缓存的过期数据与数据库保持一致 这种情况下使用 数据库更改通知 (一个新的 Oracle 数据库 g 第 版特性)将非常方便
数据库更改通知 入门
数据库更改通知 特性的用法非常简单 创建一个针对通知执行的通知处理程序 – 一个 PL/SQL 存储过程或客户端 OCI 回调函数 然后 针对要接收其更改通知的数据库对象注册一个查询 以便每当事务更改其中的任何对象并提交时调用通知处理程序 通常情况下 通知处理程序将被修改的表的名称 所做更改的类型以及所更改行的行 ID(可选)发送给客户端监听程序 以便客户端应用程序可以在响应中执行相应的处理
为了了解 数据库更改通知 特性的作用方式 请考虑以下示例 假设您的 PHP 应用程序访问 OE ORDERS 表中存储的订单以及 OE ORDER_ITEMS 中存储的订单项 鉴于很少更改已下订单的信息 您可能希望应用程序同时缓存针对 ORDERS 和 ORDER_ITEMS 表的查询结果集 要避免访问过期数据 您可以使用 数据库更改通知 它可让您的应用程序方便地获知以上两个表中所存储数据的更改
您必须先将 CHANGE NOTIFICATION 系统权限以及 EXECUTE ON DBMS_CHANGENOTIFICATION 权限授予 OE 用户 才能注册对 ORDERS 和 ORDER_ITEMS 表的查询 以便接收通知和响应对这两个表所做的 DML 或 DDL 更改 为此 可以从 SQL 命令行工具(如 SQL*Plus)中执行下列命令
CONNECT / AS SYSDBA; GRANT CHANGE NOTIFICATION TO oe; GRANT EXECUTE ON DBMS_CHANGE_NOTIFICATION TO oe;
确保将 init ora 参数 job_queue_processes 设置为非零值 以便接收 PL/SQL 通知 或者 您也可以使用下面的 ALTER SYSTEM 命令
ALTER SYSTEM SET job_queue_processes = ;
然后 在以 OE/OE 连接后 您可以创建一个通知处理程序 但首先 您必须创建将由通知处理程序使用的数据库对象 例如 您可能需要创建一个或多个数据库表 以便通知处理程序将注册表的更改记录到其中 在以下示例中 您将创建 nfresults 表来记录以下信息 更改发生的日期和时间 被修改的表的名称以及一个消息(说明通知处理程序是否成功地将通知消息发送给客户端)
CONNECT oe/oe; CREATE TABLE nfresults ( operdate DATE tblname VARCHAR ( ) rslt_msg VARCHAR ( ) );
在实际情况中 您可能需要创建更多表来记录通知事件以及所更改行的行 ID 等信息 但就本文而言 nfresults 表完全可以满足需要
使用 UTL_HTTP 向客户端发送通知
您可能还要创建一个或多个 PL/SQL 存储过程 并从通知处理程序中调用这些存储过程 从而实现一个更具可维护性和灵活性的解决方案 例如 您可能要创建一个实现将通知消息发送给客户端的存储过程 清单 是 PL/SQL 过程 sendNotification 该过程使用 UTL_HTTPPL 程序包向客户端应用程序发送更改通知
清单 使用 UTL_HTTP 向客户端发送通知
CREATE OR REPLACE PROCEDURE sendNotification(url IN VARCHAR tblname IN VARCHAR order_id IN VARCHAR ) IS req UTL_HTTP REQ; resp UTL_HTTP RESP; err_msg VARCHAR ( ); tbl VARCHAR( ); BEGIN tbl:=SUBSTR(tblname INSTR(tblname )+ ); BEGIN req := UTL_HTTP BEGIN_REQUEST(url||order_id|| & || table= ||tbl); resp := UTL_HTTP GET_RESPONSE(req); INSERT INTO nfresults VALUES(SYSDATE tblname resp reason_phrase); UTL_HTTP END_RESPONSE(resp); EXCEPTION WHEN OTHERS THEN err_msg := SUBSTR(SQLERRM ); INSERT INTO nfresults VALUES(SYSDATE tblname err_msg); END; MIT; END; /
如 清单 所示 sendNotification 以 UTL_HTTP BEGIN_REQUEST 函数发出的 HTTP 请求的形式向客户端发送通知消息 此 URL 包含 ORDERS 表中已更改行的 order_id 然后 它使用 UTL_HTTP GET_RESPONSE 获取客户端发出的响应信息 实际上 sendNotification 并不需要处理客户端返回的整个响应 而是只获取一个在 RESP 记录的 reason_phrase 字段中存储的简短消息(描述状态代码)
创建通知处理程序
现在 您可以创建一个通知处理程序 它将借助于上面介绍的 sendNotification 过程向客户端发送更改通知 来看一看 清单 中的 PL/SQL 过程 orders_nf_callback
清单 处理对 OE ORDERS 表所做更改的通知的通知处理程序
CREATE OR REPLACE PROCEDURE orders_nf_callback (ntfnds IN SYS CHNF$_DESC) IS tblname VARCHAR ( ); numtables NUMBER; event_type NUMBER; row_id VARCHAR ( ); numrows NUMBER; ord_id VARCHAR ( ); url VARCHAR ( ) := ; BEGIN event_type := ntfnds event_type; numtables := ntfnds numtables; IF (event_type = DBMS_CHANGE_NOTIFICATION EVENT_OBJCHANGE) THEN FOR i IN numtables LOOP tblname := ntfnds table_desc_array(i) table_name; IF (bitand(ntfnds table_desc_array(i) opflags DBMS_CHANGE_NOTIFICATION ALL_ROWS) = ) THEN numrows := ntfnds table_desc_array(i) numrows; ELSE numrows := ; END IF; IF (tblname = OE ORDERS ) THEN FOR j IN 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; END LOOP; END IF; MIT; END; /
如 清单 所示 此通知处理程序将 SYS CHNF$_DESC 对象用作参数 然后使用它的属性获取该更改的详细信息 在该示例中 此通知处理程序将只处理数据库为响应对注册对象进行的 DML 或 DDL 更改(也就是说 仅当通知类型为 EVENT_OBJCHANGE 时)而发布的通知 并忽略有关其他数据库事件(如实例启动或实例关闭)的通知 从以上版本开始 处理程序可以处理针对 OE ORDERS 表中每个受影响的行发出的更改通知 在本文后面的 将表添加到现有注册 部分中 您将向处理程序中添加几行代码 以便它可以处理针对 OE ORDER_ITEMS 表中被修改的行发出的通知
为更改通知创建注册创建通知处理程序后 必须为其创建一个查询注册 对于本示例而言 您必须在注册过程中对 OE ORDER 表执行查询并将 orders_nf_callback 指定为通知处理程序 您还需要在 DBMS_CHANGE_NOTIFICATION 程序包中指定 QOS_ROWIDS 选项 以便在通知消息中启用 ROWID 级别的粒度 清单 是一个 PL/SQL 块 它为 orders_nf_callback 通知处理程序创建查询注册
清单 为通知处理程序创建查询注册
DECLARE REGDS SYS CHNF$_REG_INFO; regid NUMBER; ord_id NUMBER; qosflags NUMBER; BEGIN qosflags := DBMS_CHANGE_NOTIFICATION QOS_RELIABLE + DBMS_CHANGE_NOTIFICATION QOS_ROWIDS; REGDS := SYS CHNF$_REG_INFO ( orders_nf_callback qosflags ); regid := DBMS_CHANGE_NOTIFICATION NEW_REG_START (REGDS); SELECT order_id INTO ord_id FROM orders WHERE ROWNUM< ; DBMS_CHANGE_NOTIFICATION REG_END; END; /
本示例针对 ORDERS 表创建了一个注册 并将 orders_nf_callback 用作通知处理程序 现在 如果您使用 DML 或 DDL 语句修改 ORDERS 表并提交事务 则将自动调用 orders_nf_callback 函数 例如 您可能针对 ORDERS 表执行下列 UPDATE 语句并提交该事务
UPDATE ORDERS SET order_mode = direct WHERE order_id= ; UPDATE ORDERS SET order_mode = direct WHERE order_id= ; MIT;
要确保数据库发布了通知来响应以上事务 您可以检查 nfresults 表
SELECT TO_CHAR(operdate dd mon yy hh:mi:ss ) operdate tblname rslt_msg FROM nfresults;
结果应如下所示
OPERDATE TBLNAME RSLT_MSG mar : : OE ORDERS Not Found mar : : OE ORDERS Not Found
从以上结果中可以清楚地看到 orders_nf_callback 已经正常工作 但未找到客户端脚本 在该示例中出现这种情况并不意外 这是因为您并未创建 URL 中指定的 dropResults php 脚本 有关 dropResults php 脚本的说明 请参阅本文后面的构建客户端 部分
将表添加到现有注册
前一部分介绍了如何使用更改通知服务使数据库在注册对象(在以上示例中为 ORDERS 表)发生更改时发出通知 但从性能角度而言 客户端应用程序可能更希望缓存 ORDER_ITEMS 表而非 ORDERS 表本身的查询结果集 这是因为它在每次访问订单时 不得不从 ORDERS 表中只检索一行 但同时必须从 ORDER_ITEMS 表中检索多个行 在实际情况中 订单可能包含数十个甚至数百个订单项
由于您已经对 ORDERS 表注册了查询 因此不必再创建一个注册来注册对 ORDER_ITEMS 表的查询了 相反 您可以使用现有注册 为此 您首先需要检索现有注册的 ID 可以执行以下查询来完成此工作
SELECT regid table_name FROM user_change_notification_regs;
结果可能如下所示
REGID TABLE_NAME OE ORDERS
获取注册 ID 后 可以使用 DBMS_CHANGE_NOTIFICATION ENABLE_REG 函数将一个新对象添加到该注册 如下所示
DECLARE ord_id NUMBER; BEGIN DBMS_CHANGE_NOTIFICATION ENABLE_REG( ); SELECT order_id INTO ord_id FROM order_items WHERE ROWNUM < ; 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;
然后 返回清单 在以下代码行之后
IF (tblname = OE ORDERS ) THEN FOR j IN 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 = WHERE order_id= AND line_item_id= ; UPDATE ORDER_ITEMS SET quantity = WHERE order_id= AND line_item_id= ; MIT;
然后 检查 nfresults 表 如下所示
SELECT TO_CHAR(operdate dd mon yy hh:mi:ss ) operdate rslt_msg FROM nfresults WHERE tblname = OE ORDER_ITEMS ;
输出可能如下所示
OPERDATE RSLT_MSG mar : : Not Found
您可能很奇怪为什么只向 nfresults 表中插入了一行 – 毕竟您更新了 ORDER_ITEMS 表中的两行 实际上 这两个更新了的行具有相同的 order_id – 即它们属于同一订单 此处 我们假设客户端应用程序将使用一个语句选择订单的所有订单项 因此它并不需要确切知道已经更改了某个订单的哪些订单项 相反 客户端需要知道其中至少修改 删除或插入了一个订单项的订单 ID
构建客户端
现在 您已经针对 ORDERS 和 ORDER_ITEMS 表创建了注册 下面我们将了解一下访问这些表中存储的订单及其订单项的客户端应用程序如何使用更改通知 为此 您可以构建一个 PHP 应用程序 它将缓存针对以上表的查询结果 并采取相应的操作来响应有关对这些表所做更改的通知(从数据库服务器中收到这些通知) 一个简单的方法是使用 PEAR::Cache_Lite 程序包 它为您提供了一个可靠的机制来使缓存数据保持最新状态 尤其是 您可以使用 Cache_Lite_Function 类(PEAR::Cache_Lite 程序包的一部分) 通过该类您可以缓存函数调用
例如 您可以创建一个函数来执行下列任务 建立数据库连接 针对该数据库执行 select 语句 获取检索结果并最终以数组形式返回结果 然后 您可以通过 Cache_Lite_Function 实例的 call 方法缓存由该函数返回的结果数组 以便可以从本地缓存而不是从后端数据库读取这些数组 这样可以显著提高应用程序的性能 然后 在收到缓存数据更改的通知时 您将使用 Cache_Lite_Function 实例的 drop 方法删除缓存中的过期数据
回过头来看看本文的示例 您可能要创建两个函数 用于应用程序与数据库交互 第一个函数将查询 ORDERS 表并返回具有指定 ID 的订单 而另一个函数将查询 ORDER_ITEMS 表并返回该订单的订单项 清单 显示了包含 getOrderFields 函数(该函数接受订单 ID 并返回一个包含所检索到订单的某些字段的关联数组)的 getOrderFields php 脚本
清单 获取指定订单的字段
<?php //File:getOrderFields php require_once connect php ; function getOrderFields($order_no) if (!$rsConnection = GetConnection()) return false; $strSQL = SELECT TO_CHAR(ORDER_DATE) ORDER_DATE CUSTOMER_ID ORDER_TOTAL FROM ORDERS WHERE order_id =:order_no ; $rsStatement = oci_parse($rsConnection $strSQL); oci_bind_by_name($rsStatement :order_no $order_no ); if (!oci_execute($rsStatement)) $err = oci_error(); print $err[ message ]; trigger_error( Query failed: $err[ message ]); return false; $results = oci_fetch_assoc($rsStatement); return $results; ?>
清单 是 getOrderItems php 脚本 该脚本包含 getOrderItems 函数 该函数接受订单 ID 并返回一个二维数组 该数组包含表示订单的订单项的行
清单 获取指定订单的订单项
<?php //File:getOrderItems php require_once connect php ; function getOrderItems($order_no) if (!$rsConnection = GetConnection()) return false; $strSQL = SELECT * FROM ORDER_ITEMS WHERE order_id =:order_no ORDER BY line_item_id ; $rsStatement = oci_parse($rsConnection $strSQL); oci_bind_by_name($rsStatement :order_no $order_no ); if (!oci_execute($rsStatement)) $err = oci_error(); trigger_error( Query failed: $err[ message ]); return false; $nrows = oci_fetch_all($rsStatement $results); return array ($nrows $results); ?>
注意 以上两个函数都需要 connect php 脚本 该脚本应包含返回数据库连接的 GetConnection 函数 清单 就是 connect php 脚本
清单 获取数据库连接
<?php //File:connect php function GetConnection() $dbHost = dbserverhost ; $dbHostPort= ; $dbServiceName = orclR ; $usr = oe ; $pswd = oe ; $dbConnStr = (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST= $dbHost ) (PORT= $dbHostPort ))(CONNECT_DATA=(SERVICE_NAME= $dbServiceName ))) ; if(!$dbConn = oci_connect($usr $pswd $dbConnStr)) $err = oci_error(); trigger_error( Failed to connect $err[ message ]); return false; return $dbConn; ?>
现在 您已经创建了与数据库通信所需的所有函数 下面我们将了解一下 Cache_Lite_Function 类的工作方式 清单 是 testCache php 脚本 该脚本使用 Cache_Lite_Function 类缓存以上函数的结果
清单 使用 PEAR::Cache_Lite 缓存
<?php //File:testCache php require_once getOrderItems php ; require_once getOrderFields php ; require_once Cache/Lite/Function php ; $options = array( cacheDir => /tmp/ lifeTime => ); if (!isset($_GET[ order_no ])) die( The order_no parameter is required ); $order_no=$_GET[ order_no ]; $cache = new Cache_Lite_Function($options); if ($orderfields = $cache >call( getOrderFields $order_no)) print <h >ORDER #$order_no</h >\\n ; print <table> ; print <tr><td>DATE:</td><td> $orderfields[ ORDER_DATE ] </td></tr> ; print <tr><td>CUST_ID:</td><td> $orderfields[ CUSTOMER_ID ] </td></tr> ; print <tr><td>TOTAL:</td><td> $orderfields[ ORDER_TOTAL ] </td></tr> ; print </table> ; else print Some problem occurred while getting order fields!\\n ; $cache >drop( getOrderFields $order_no); if (list($nrows $orderitems) = $cache >call( getOrderItems $order_no)) //print <h >LINE ITEMS IN ORDER #$order_no</h > ; print <table border= > ; print <tr>\\n ; while (list($key $value) = each($orderitems)) print <th>$key</th>\\n ; print </tr>\\n ; for ($i = ; $i < $nrows; $i++) print <tr> ; print <td> $orderitems[ ORDER_ID ][$i] </td> ; print <td> $orderitems[ LINE_ITEM_ID ][$i] </td> ; print <td> $orderitems[ PRODUCT_ID ][$i] </td> ; print <td> $orderitems[ UNIT_PRICE ][$i] </td> ; print <td> $orderitems[ QUANTITY ][$i] </td> ; print </tr> ; print </table> ; else print Some problem occurred while getting order line items ; $cache >drop( getOrderItems $order_no); ?>
清单 中的 testCache php 脚本应与 order_no URL 参数(代表 OE ORDER 表中存储的订单 ID)一起被调用 例如 要检索与 ID 为 的订单相关的信息 需要在浏览器中输入如下所示的 URL
结果 浏览器将生成以下输出
ORDER #
DATE:
JUN AM
CUST_ID:
TOTAL:
ORDER_ID
LINE_ITEM_ID
PRODUCT_ID
UNIT_PRICE
QUANTITY
现在 如果您单击浏览器中的 reload 按钮 testCache php 脚本将不会再次调用 getOrderFields 和 getOrderItems 函数 相反 它将从本地缓存中读取它们的结果 因此 从现在起的 小时(因为 lifeTime 设置为 秒)以内 本地缓存即可满足使用 order_no= 的每个 getOrderFields 或 getOrderItems 调用的需要 但请注意 Cache_Lite_Function 类未提供 API 来测试具有给定参数的给定函数是否存在可用缓存 因此 要确定每次使用相同参数调用函数时应用程序是实际上读取缓存还是仍执行该函数可能有点棘手 例如 在以上示例中 要确保缓存机制正常工作 您可以临时更改 connect php 脚本中指定的连接信息 以便它无法建立数据库连接 比如指定一个错误的数据库服务器主机名称 然后再次使用 order_no= 运行 testCache php 脚本 如果缓存正常工作 浏览器的输出应与先前的一样
此外 您还可以检查缓存目录 该目录作为 cacheDir 选项的值(在该示例中为 /tmp)传递给 Cache_Lite_Function 类的构造函数 在该目录中 您将找到两个刚创建的缓存文件 这些文件的名称类似于 cache_ b b b aee ad e bd d a ec_ ad d f cd f c a 注意 如果您是一位 Windows 用户 则可能要使用 %SystemDrive%\\temp 目录保存缓存文件 如果是这样 则必须将 cacheDir 选项设置为 /temp/
验证缓存机制正常工作后 可以接着创建一个 PHP 来处理从数据库服务器收到的更改通知 清单 是 dropResult php 脚本 数据库服务器将调用该脚本来响应 ORDERS 和 ORDER_ITEMS 表的更改
清单 处理从数据库服务器收到的更改通知
<?php //File:dropResults php require_once Cache/Lite/Function php ; $options = array( cacheDir => /tmp/ ); $cache = new Cache_Lite_Function($options); if (isset($_GET[ order_no ])&& isset($_GET[ table ])) if($_GET[ table ]== ORDER_ITEMS ) $cache >drop( getOrderItems $_GET[ order_no ]); if ($_GET[ table ]== ORDERS ) $cache >drop( getOrderFields $_GET[ order_no ]); ?>
创建 dropResult php 脚本后 请确保在通知处理程序中指定的 URL(如清单 所示)正确 然后 在 SQL*Plus 或类似工具中以 OE/OE 连接 并执行 UPDATE 语句 这些语句将影响本部分先前通过 testCache php 脚本访问的同一订单(此处是 ID 为 的订单)
UPDATE ORDERS SET order_mode = direct WHERE order_id= ; UPDATE ORDER_ITEMS SET quantity = WHERE order_id= AND line_item_id= ; UPDATE ORDER_ITEMS SET quantity = WHERE order_id= AND line_item_id= ; MIT;
为响应以上更新 本文前面介绍的通知处理程序将逐个使用下列 URL 运行 dropResults php 脚本两次
;table=ORDERS ;table=ORDER_ITEMS
从 清单 中您可以清楚地看到 dropResult php 脚本在从数据库服务器收到更改通知后并未刷新缓存 它只是删除了包含过期数据的缓存文件 因此 如果现在检查缓存目录 则将看到在使用 order_no= 运行 testCache php 脚本时创建的缓存文件已经消失 这实际上意味着 testCache php 在下次请求与 ID 为 的订单相关的数据时将从后端数据库而非本地缓存中获取该数据
您会发现 在应用程序请求的结果集很有可能在应用程序使用它之前更改的情况下该方法将很有用 就本文的示例而言 这意味着与特定订单相关的数据可能在 testCache php 访问该订单之前多次更改 这样 应用程序会因在从数据库服务器收到更改通知后立即刷新它的缓存而做了大量不必要的工作
但如果您希望 dropResult php 脚本在收到更改通知后立即刷新缓存 则可以在调用 drop 方法后调用 Cache_Lite_Function 实例的 call 方法 并为这两个调用指定相同的参数 在该情形下 还应确保包含 getOrderFields php 和 getOrderItems php 脚本 以便 dropResults php 可以调用 getOrderFields 和 getOrderItems 函数来刷新缓存 清单 是修改后的 dropResult php 脚本
清单 在收到更改通知后立即刷新缓存
<?php //File:dropResults php require_once Cache/Lite/Function php ; require_once getOrderItems php ; require_once getOrderFields php ; $options = array( cacheDir => /tmp/ lifeTime => ); $cache = new Cache_Lite_Function($options); if (isset($_GET[ order_no ])&& isset($_GET[ table ])) if($_GET[ table ]== ORDER_ITEMS ) $cache >drop( getOrderItems $_GET[ order_no ]); $cache >call( getOrderItems $_GET[ order_no ]); if ($_GET[ table ]== ORDERS ) $cache >drop( getOrderFields $_GET[ order_no ]); $cache >call( getOrderFields $_GET[ order_no ]); ?>
如果存储在 ORDERS 和 ORDER_ITEMS 表中的数据很少更改并且应用程序频繁访问它 则以上方法可能很有用
cha138/Article/program/Oracle/201311/18960相关参考
通过以上的介绍可以看出hibernate主要从以下几个方面来优化查询性能 降低访问数据库的频率减少select语句的数目实现手段有使用迫切左外连接或迫切内连接对延迟检索或立即检索设置批量检索数目
巧用缓存提高ASP应用程序的性能 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!lishixinzh
在应用程序开发中可以通过函数来提高系统的性能与代码的重复利用在SQLServer数据库中也可以通过自定义函数来提高服务器的性能用户自定义函数可以从外部接受必要的参数并在内部执行一些复杂的操作最后返
用PHP连mysql和oracle数据库性能比较 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
使用值类型的ToString方法 在连接字符串时经常使用+号直接将数字添加到字符串中这种方法虽然简单也可以得到正确结果但是由于涉及到不同的数据类型数字需要通过装箱操作转化为引用类型才可以添加到字
PHP程序加速探索之缓存输出 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 内容缓存输出PEAR
PHP之APC缓存详细介绍 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! APC缓存简介 AP
深入Nginx+PHP缓存详解 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!以下是对Nginx中的
一高级扫描使用举例 通常情况下在数据查询的时候数据库会利用索引或者通过全表扫描来查找数据但是如果需要的数据在数据库中存储不连续或者需要查找的记录比较多时此时索引的效果就会大打折扣在这种情况下数据
Hibernate在解决性能问题方面做得非常好有了它的缓存机制使用第三方缓存和数据库连接池就较好的解决的性能问题但这些还不够hibernate给了开发者足够的自由让开发者自己去控制性能问题 学习