0

複数のテーブルを結合する場合と MINUS を使用してレコードを削除する場合のパフォーマンスを誰かが説明できることを願っています。他のいくつかのスタック オーバーフローの質問を見ましたが、探しているものが見つかりませんでした。

これら2つのクエリは同じ出力を生成すると思っていましたが、特にスタックオーバーフローの投稿から、「結合を使用して結合を使用してください!」と常に聞いていましたが、より高速であることが期待されていました...

これは私が実行した最初のクエリで、はるかに遅いと思っていましたが、実行には数分しかかかりません...

select some_id
  from table1
MINUS
select some_id
  from table2
 where table2.value = 'some_value'
MINUS
select some_id
  from table3
 where table3.value = 'some_value'
 group by some_id

これは私がより速いと思った 2 番目のクエリですが、現在 3 時間以上実行されています (終わりが見えない?)

select some_id
  from table1
       join table2 on table1.id=table2.id
       join table3 on table1.id=table3.id
 where table2.value = 'some_value'
    or table3.value = 'some_value'
 group by some_id

3 つのテーブルすべてに 100 万を超えるレコードがあり、それぞれ最大 1,500 万のレコードがあることに注意してください。

編集

申し訳ありませんが、この 2 つのシナリオだけに興味があるので、この質問では NOT EXISTS の使用を回答として避けていたことをお知らせするつもりでした。

4

2 に答える 2

0

このバージョンを試してください:

select some_id
from table1
where not exists (select 1 from table2 t2 on t1.id = t2.id and t2.value = 'some_value') or
      not exists (select 1 from table3 t3 on t1.id = t3.id and t3.value = 'some_value')

table2(id, value)最高のパフォーマンスを得るには、およびにインデックスを作成する必要がありtable3(id, value)ます。

于 2015-04-16T20:09:22.237 に答える
0

まず、インデックスが適切に配置されていることを確認してください。

計画を確認するには、テーブル全体のスキャンを使用している場合は、インデックスの作成に進みます。それ以外の場合は、非常に長い時間がかかります。

plsql 開発者がいる場合は、SQL ウィンドウにクエリを貼り付けて F5 キーを押すと、Explain Plan が表示されます。

またはこれを行うこともできます

SCOTT@research 17-APR-15>       EXPLAIN PLAN FOR
  2        select empno
  3            from emp
  4          MINUS
  5          select empno
  6            from empp
  7           where empp.empno = '7839'
  8          MINUS
  9          select empno
 10            from emppp
 11           where emppp.empno = '7902'
 12           group by empno
 13           ;

Explained.

SCOTT@research 17-APR-15> SET LINESIZE 130
SCOTT@research 17-APR-15> SET PAGESIZE 0
SCOTT@research 17-APR-15> SELECT *
  2  FROM   TABLE(DBMS_XPLAN.DISPLAY);
Plan hash value: 4222598102

---------------------------------------------------------------------------------
| Id  | Operation              | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |        |    14 |    82 |    10  (90)| 00:00:01 |
|   1 |  MINUS                 |        |       |       |            |          |
|   2 |   MINUS                |        |       |       |            |          |
|   3 |    SORT UNIQUE NOSORT  |        |    14 |    56 |     2  (50)| 00:00:01 |
|   4 |     INDEX FULL SCAN    | PK_EMP |    14 |    56 |     1   (0)| 00:00:01 |
|   5 |    SORT UNIQUE NOSORT  |        |     1 |    13 |     4  (25)| 00:00:01 |
|*  6 |     TABLE ACCESS FULL  | EMPP   |     1 |    13 |     3   (0)| 00:00:01 |
|   7 |   SORT UNIQUE NOSORT   |        |     1 |    13 |     4  (25)| 00:00:01 |
|   8 |    SORT GROUP BY NOSORT|        |     1 |    13 |     4  (25)| 00:00:01 |
|*  9 |     TABLE ACCESS FULL  | EMPPP  |     1 |    13 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   6 - filter("EMPP"."EMPNO"=7839)
   9 - filter("EMPPP"."EMPNO"=7902)

Note
-----
   - dynamic sampling used for this statement (level=2)

26 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 2137789089

---------------------------------------------------------------------------------------------
| Id  | Operation                         | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |         |  8168 | 16336 |    29   (0)| 00:00:01 |
|   1 |  COLLECTION ITERATOR PICKLER FETCH| DISPLAY |  8168 | 16336 |    29   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

または、autotrace を使用する場合は、

set autotrace on explain

これは、それがどのように見えるか、

SCOTT@research 17-APR-15> select empno
  2    from emp
  3  MINUS
  4  select empno
  5    from empp
  6   where empp.empno = '7839'
  7  MINUS
  8  select empno
  9    from emppp
 10   where emppp.empno = '7902'
 11   group by empno
 12   ;

     EMPNO
----------
       234
      7499
      7521
      7566
      7654
      7698
      7782
      7788
      7844
      7876
      7900
      7934

12 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 4222598102

---------------------------------------------------------------------------------
| Id  | Operation              | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |        |    14 |    82 |    10  (90)| 00:00:01 |
|   1 |  MINUS                 |        |       |       |            |          |
|   2 |   MINUS                |        |       |       |            |          |
|   3 |    SORT UNIQUE NOSORT  |        |    14 |    56 |     2  (50)| 00:00:01 |
|   4 |     INDEX FULL SCAN    | PK_EMP |    14 |    56 |     1   (0)| 00:00:01 |
|   5 |    SORT UNIQUE NOSORT  |        |     1 |    13 |     4  (25)| 00:00:01 |
|*  6 |     TABLE ACCESS FULL  | EMPP   |     1 |    13 |     3   (0)| 00:00:01 |
|   7 |   SORT UNIQUE NOSORT   |        |     1 |    13 |     4  (25)| 00:00:01 |
|   8 |    SORT GROUP BY NOSORT|        |     1 |    13 |     4  (25)| 00:00:01 |
|*  9 |     TABLE ACCESS FULL  | EMPPP  |     1 |    13 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   6 - filter("EMPP"."EMPNO"=7839)
   9 - filter("EMPPP"."EMPNO"=7902)

Note
-----
   - dynamic sampling used for this statement (level=2)

SCOTT@research 17-APR-15>



SCOTT@research 17-APR-15> select emp.empno
  2    from emp
  3         join empp on emp.empno=empp.empno
  4         join emppp on emp.empno=emppp.empno
  5   where empp.empno = '7839'
  6      or emppp.empno = '7902'
  7   group by emp.empno
  8  ;

     EMPNO
----------
      7839
      7902


Execution Plan
----------------------------------------------------------
Plan hash value: 1435156579

-------------------------------------------------------------------------------
| Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |        |     1 |    30 |     8  (25)| 00:00:01 |
|   1 |  HASH GROUP BY       |        |     1 |    30 |     8  (25)| 00:00:01 |
|*  2 |   HASH JOIN          |        |     1 |    30 |     7  (15)| 00:00:01 |
|   3 |    NESTED LOOPS      |        |     6 |   102 |     3   (0)| 00:00:01 |
|   4 |     TABLE ACCESS FULL| EMPPP  |     6 |    78 |     3   (0)| 00:00:01 |
|*  5 |     INDEX UNIQUE SCAN| PK_EMP |     1 |     4 |     0   (0)| 00:00:01 |
|   6 |    TABLE ACCESS FULL | EMPP   |    10 |   130 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("EMP"."EMPNO"="EMPP"."EMPNO")
       filter("EMPP"."EMPNO"=7839 OR "EMPPP"."EMPNO"=7902)
   5 - access("EMP"."EMPNO"="EMPPP"."EMPNO")

Note
-----
   - dynamic sampling used for this statement (level=2)
于 2015-04-17T02:09:59.737 に答える