Oracle
 sql >> Baza danych >  >> RDS >> Oracle

problem z wydajnością:różnica między select s.* a select *

są to oczywiście dwa różne zapytania. plan MOŻE się zmienić, a wybrane są inne. np. w sth.* może wybierać pełne/szybkie pełne skanowanie indeksu na lewej połączonej tabeli. podczas gdy na pierwszym będzie to prawdopodobnie pełne skanowanie tabeli.

aby jeszcze bardziej Ci pomóc, czy możemy zobaczyć plany? najlepiej zrobić to w SQL*PLUS

set timing on
set autotrace on traceonly

select s.* from sales_unit s left join sales_unit_relation r on (s.sales_unit_id = r.sales_unit_child_id) where r.sales_unit_child_id is null;

select * from sales_unit s left join sales_unit_relation r on (s.sales_unit_id = r.sales_unit_child_id) where r.sales_unit_child_id is null;

EDYTUJ

biorąc pod uwagę twój plan wyjaśnień, widzisz KARDYNAŁOŚĆ=1 na każdym kroku? zebrałeś statystyki, gdy stoły były puste! zobacz to:

SQL> select s.* from sales_unit s left join sales_unit_relation r on (s.sales_unit_id = r.child_sales_unit_id) where r.child_sales_unit_id is null;

no rows selected

Elapsed: 00:00:03.19

Execution Plan
----------------------------------------------------------
Plan hash value: 1064670292

------------------------------------------------------------------------------------
| Id  | Operation          | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |               |     1 |    48 |    27  (86)| 00:00:01 |
|   1 |  NESTED LOOPS ANTI |               |     1 |    48 |    27  (86)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| SALES_UNIT    |     1 |    35 |     2   (0)| 00:00:01 |
|*  3 |   INDEX RANGE SCAN | SALES_REL_IX1 |     1 |    13 |    25  (92)| 00:00:01 |
------------------------------------------------------------------------------------

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

   3 - access("S"."SALES_UNIT_ID"="R"."CHILD_SALES_UNIT_ID")


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
     200314  consistent gets
       2220  physical reads
          0  redo size
        297  bytes sent via SQL*Net to client
        339  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed

więc zobacz, że użył 200314 IO i zajęło kilka sekund. Zobacz także ROWS =1 na każdym kroku (tj. pełne skany).. zbierz statystyki:

SQL> begin dbms_stats.gather_table_stats(user, 'SALES_UNIT', degree=>8, cascade=>true); end;
  2  /

PL/SQL procedure successfully completed.

SQL> begin dbms_stats.gather_table_stats(user, 'SALES_UNIT_RELATION', degree=>8, cascade=>true); end;
  2  /

PL/SQL procedure successfully completed.

a teraz rerun:SQL> wybierz s.* z sales_unit s left dołącz do sales_unit_relation r on (s.sales_unit_id =r.child_sales_unit_id) gdzie r.child_sales_unit_id ma wartość null;

no rows selected

Elapsed: 00:00:00.84

Execution Plan
----------------------------------------------------------
Plan hash value: 2005864719

-----------------------------------------------------------------------------------------------
| Id  | Operation             | Name          | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |               |   912 | 18240 |       |  1659   (3)| 00:00:20 |
|*  1 |  HASH JOIN ANTI       |               |   912 | 18240 |  2656K|  1659   (3)| 00:00:20 |
|   2 |   TABLE ACCESS FULL   | SALES_UNIT    |   100K|  1472K|       |    88   (3)| 00:00:02 |
|   3 |   INDEX FAST FULL SCAN| SALES_REL_IX1 |   991K|  4841K|       |   618   (3)| 00:00:08 |
-----------------------------------------------------------------------------------------------

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

   1 - access("S"."SALES_UNIT_ID"="R"."CHILD_SALES_UNIT_ID")


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
       2537  consistent gets
          0  physical reads
          0  redo size
        297  bytes sent via SQL*Net to client
        339  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed

SQL>

teraz użyliśmy tylko 2537 pobiera, a plan pokazuje właściwe ROWS i złącze HASH (lepiej dla naszych potrzeb). moje tabele testowe są prawdopodobnie mniejsze niż twoje prawdziwe, dlatego czasy są bliższe




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zamienić wartości sqlldr

  2. Masowe aktualizacje właściwości raportów i formularzy Oracle 11g

  3. Tabela utworzona w procedurze zostaje usunięta, pojawia się błąd kompilacji procedury

  4. Jak wyodrębnić podciąg z ciągu w Oracle/SQLite?

  5. Zapytanie Oracle o uzyskanie określonej daty