Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Oracle中为前端应用程序使用游标是否有利?_Oracle_Plsql_Cursor - Fatal编程技术网

在Oracle中为前端应用程序使用游标是否有利?

在Oracle中为前端应用程序使用游标是否有利?,oracle,plsql,cursor,Oracle,Plsql,Cursor,我的数据库中有两个表。每个表有2000条记录。因为我有大量的记录,所以我想编写检索记录的最佳代码用户详细信息表格为: +---------+-----------+-----------+ | user_id | user_name | join_date | +---------+-----------+-----------+ 参考用户详细信息的第二个表是: +---------+-----------+-----------+ | user_id | fav_color | fav_di

我的数据库中有两个表。每个表有2000条记录。因为我有大量的记录,所以我想编写检索记录的最佳代码<代码>用户详细信息表格为:

+---------+-----------+-----------+
| user_id | user_name | join_date |
+---------+-----------+-----------+
参考用户详细信息的第二个表是:

+---------+-----------+-----------+
| user_id | fav_color | fav_dish  |
+---------+-----------+-----------+
我有两种方法第一种:

SELECT UD.*,FAV.FAV_COLOR, FAV.FAV_DISH FROM USER_DETAILS UD, FAV_DETAILS FAV 
    WHERE UD.USER_ID = FAV.USER_ID;
第二种方法是编写PL/SQL过程,即:

DECLARE
CURSOR C1(X NUMBER) IS SELECT * FROM USER_DETAILS WHERE USER_ID = X;
CURSOR C2 IS SELECT * FROM USER_FAV;
Y NUMBER := &USER_ID;
BEGIN
FOR C IN C1(Y)
    LOOP
    DBMS_OUTPUT.PUT_LINE('USER DETAILS');
    DBMS_OUTPUT.PUT_LINE('----------------');
    FOR D IN C2
        LOOP
        IF C.DEPTNO = D.DEPTNO THEN
            DBMS_OUTPUT.PUT_LINE(RPAD(C.USER_ID,10)||RPAD(C.USER_NAME,10)||RPAD(D.FAV_COLOR,10));
        END IF;
    END LOOP;
END LOOP;
END;
哪种代码可以提供更好的性能?为什么?我想获得用户的完整详细信息

如果我使用cursor,我会得到从服务器到SGA的所有记录吗?我将在JSP页面中使用该数据库,该页面仅可由移动设备访问


由于移动设备中的互联网对于我的目标用户来说非常慢(大约10KB),因此我担心带宽。在我看来,我发现执行连接将执行笛卡尔乘积并检查匹配结果,这将从1000*1000个条件中提取一个条件,而PL/SQL块中的检查条件仅为1000+1000。它减少了条件的数量。但据我所知,游标将在客户机内存中创建一个影子页,并创建表。这意味着它将从服务器获取所有数据并存储在客户机中。这一点我说的对吗?

当您希望在结果的每一行上都有一个指针以执行进一步的操作时,请使用游标。如果您只需要一个
select
语句,只需执行
select
语句即可。光标将是一个过度的杀伤力。保持简单

你可以阅读汤姆·凯特的咒语:

如果可能的话,您应该在一条SQL语句中执行此操作。
如果不能在单个SQL语句中执行,请在PL/SQL中执行。
如果不能在PL/SQL中执行此操作,请尝试使用Java存储过程。
如果不能在Java中执行,请在C外部过程中执行。
如果您不能在C外部例程中执行此操作,您可能需要认真思考为什么需要执行此操作

基本上,通过使用plsql存储过程,您可以来回地从sql引擎移动到plsql引擎。此外,如果您有正确的索引,并且正确构建查询,那么sql优化器可能会使事情变得比您更快


通常使用单个select语句将具有更好的性能
通过一次选择,您将点击RDBMS Sql引擎一次,RDMS将使用内部过程(索引、现金查询…)提高性能

以编程方式(忽略内部RDMS功能)
在第一个查询中,您执行的搜索的效率顺序为O(n) 在第二条plsql语句中,通过使用嵌套循环,您正在以O(n^2)的效率顺序进行搜索

查询执行两种不同的操作。SELECT获取所有用户,而过程获取单个用户。你到底想做这两件事中的哪一件?尽管select得到了所有用户,但我怀疑它速度更快。用循环替换连接很少是个好主意。@JoachimIsaksson:连接将执行笛卡尔乘积,然后它将从满足条件的行中选择一行。所以它将迭代1000*1000次。但是循环不会重复那么多次。在用户id上创建一个索引,那么连接的性能就会好得多。如果没有索引,join和cursor都将以顺序搜索结束,这将导致性能下降。此外,C2光标必须穿过所有行,而不考虑给定的用户id。显然,联接工作得更好。@Dibya Oracle不会执行笛卡尔联接,只要您在
join/ON
子句或
WHERE
子句(您在
SELECT
中执行后者)中连接表,一些不太成熟的数据库可能,因此,使用
JOIN/ON
语法是一种很好的形式。请看一下我的编辑部分。我又补充了几个细节,这是一个很好的建议。我将坚持使用简单的SQL语句,但我的问题没有得到解决,在这种情况下,哪种性能更好。。。但是作为一条黄金法则——使用sql而不是plsql(这是咒语所说的)。你为什么不试试呢?检查AskTom Post的解释计划。它有很多我需要的信息。