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