2

我的数据库中有两个表。每个表有 2000 条记录。由于我有大量记录,我想编写用于检索记录的最佳代码。USER_DETAILS表是:

+---------+-----------+-----------+
| user_id | user_name | join_date |
+---------+-----------+-----------+

引用表的第二个表USER_DETAILS是:

+---------+-----------+-----------+
| 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;

哪个代码会提供更好的性能,为什么?我想获取用户的完整详细信息。

如果我使用游标,我会从服务器获取所有记录到 SGA 吗?我将在仅由移动设备访问的 JSP 页面中使用此数据库。

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

4

3 回答 3

2

你可以在这里阅读Tom Kyte 的口头禅:

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

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

这是另一个很好的 AskTom 帖子

于 2013-02-19T06:12:23.663 回答
1

通常使用单个选择语句将
通过单个选择获得更好的性能,您将使用一次 RDBMS Sql 引擎,RDMS 将使用内部过程(索引、现金查询......)提高性能。

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

于 2013-02-19T08:25:48.570 回答
0

当您希望在结果的每一行上都有一个指针以执行进一步的操作时,请使用光标。如果你只需要一个select陈述,就做一个select陈述。光标将是一个矫枉过正。把事情简单化。

于 2013-02-19T05:47:53.060 回答