如何加快查询速度?

时间:2014-08-11 17:43:04

标签: sql performance oracle oracle11g oracle-sqldeveloper

我正在尝试对一个非常大的数据集运行查询,虽然由于我在oracle中缺乏专业知识,我似乎无法加速它并且查询需要很长时间,因为有很多数据行。我附上解释计划,以显示究竟在做什么。任何帮助将不胜感激。

select 
    a.customer_id, 
    c.vm_mor, 
    c.vm_id, 
    d.license_id, 
    e.product, 
    f.guest_os_id 
from 
    customers a, 
    vm_groups b, 
    vms c, 
    vm_licenses d, 
    licenses e, 
    vm_compute_histories f 
where 
    a.customer_id = b.customer_id 
    and b.vm_group_id = c.vm_group_id 
    and c.vm_id = d.vm_id 
    and d.license_id = e.license_id
    and c.vm_id = f.vm_id 
order by 
    a.customer_id, vm_id

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3321561485

---------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name                 | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |                      |  7575 |   591K|    36  (12)| 00:00:01 |
|   1 |  SORT ORDER BY             |                      |  7575 |   591K|    36  (12)| 00:00:01 |
|*  2 |   HASH JOIN                |                      |  7575 |   591K|    35   (9)| 00:00:01 |
|*  3 |    HASH JOIN               |                      |  1238 | 87898 |    17  (12)| 00:00:01 |
|   4 |     TABLE ACCESS FULL      | LICENSES             |    45 |  1665 |     3   (0)| 00:00:01 |
|*  5 |     HASH JOIN              |                      |  1241 | 42194 |    14  (15)| 00:00:01 |
|   6 |      VIEW                  | index$_join$_002     |    46 |   368 |     3  (34)| 00:00:01 |
|*  7 |       HASH JOIN            |                      |       |       |            |          |
|   8 |        INDEX FAST FULL SCAN| XIF1VM_GROUPS        |    46 |   368 |     1   (0)| 00:00:01 |
|   9 |        INDEX FAST FULL SCAN| XPKVM_GROUPS         |    46 |   368 |     1   (0)| 00:00:01 |
|* 10 |      HASH JOIN             |                      |  1241 | 32266 |    11  (10)| 00:00:01 |
|  11 |       TABLE ACCESS FULL    | VMS                  |  1062 | 18054 |     7   (0)| 00:00:01 |
|  12 |       INDEX FAST FULL SCAN | XIE1VM_LICENSES      |  1241 | 11169 |     3   (0)| 00:00:01 |
|  13 |    TABLE ACCESS FULL       | VM_COMPUTE_HISTORIES |  7780 | 70020 |    17   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------

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

   2 - access("C"."VM_ID"="F"."VM_ID")
   3 - access("D"."LICENSE_ID"="E"."LICENSE_ID")
   5 - access("B"."VM_GROUP_ID"="C"."VM_GROUP_ID")
   7 - access(ROWID=ROWID)
  10 - access("C"."VM_ID"="D"."VM_ID")

29 rows selected.

以下是要求的解释计划:

这是查询:

SELECT a.customer_id,
         c.vm_mor,
         c.vm_id,
         d.license_id,
         e.product,
         f.guest_os_id
    FROM customers a,
         vms c,
         vm_licenses d,
         licenses e,
         vm_compute_histories f
   WHERE     EXISTS
                 (SELECT 'X'
                    FROM vm_groups b
                   WHERE     a.customer_id = b.customer_id
                         AND c.vm_group_id = b.vm_group_id)
         AND c.vm_id = d.vm_id
         AND d.license_id = e.license_id
         AND c.vm_id = f.vm_id
ORDER BY a.customer_id, c.vm_id
/

计划:

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1991801996

----------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name                 | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                      |  2354 |   144K|    31  (13)| 00:00:01 |
|   1 |  SORT ORDER BY                    |                      |  2354 |   144K|    31  (13)| 00:00:01 |
|*  2 |   HASH JOIN                       |                      |  2354 |   144K|    30  (10)| 00:00:01 |
|   3 |    NESTED LOOPS                   |                      |   388 | 20952 |    15  (20)| 00:00:01 |
|*  4 |     HASH JOIN                     |                      |   388 | 19400 |    15  (20)| 00:00:01 |
|   5 |      SORT UNIQUE                  |                      |    46 |   368 |     3  (34)| 00:00:01 |
|   6 |       VIEW                        | index$_join$_006     |    46 |   368 |     3  (34)| 00:00:01 |
|*  7 |        HASH JOIN                  |                      |       |       |            |          |
|   8 |         INDEX FAST FULL SCAN      | XIF1VM_GROUPS        |    46 |   368 |     1   (0)| 00:00:01 |
|   9 |         INDEX FAST FULL SCAN      | XPKVM_GROUPS         |    46 |   368 |     1   (0)| 00:00:01 |
|* 10 |      HASH JOIN                    |                      |   388 | 16296 |    12  (17)| 00:00:01 |
|  11 |       MERGE JOIN                  |                      |   388 |  9700 |     5  (20)| 00:00:01 |
|  12 |        TABLE ACCESS BY INDEX ROWID| LICENSES             |    22 |   374 |     2   (0)| 00:00:01 |
|  13 |         INDEX FULL SCAN           | XPKLICENSES          |    22 |       |     1   (0)| 00:00:01 |
|* 14 |        SORT JOIN                  |                      |   388 |  3104 |     3  (34)| 00:00:01 |
|  15 |         INDEX FAST FULL SCAN      | XIE1VM_LICENSES      |   388 |  3104 |     2   (0)| 00:00:01 |
|  16 |       TABLE ACCESS FULL           | VMS                  |   953 | 16201 |     6   (0)| 00:00:01 |
|* 17 |     INDEX UNIQUE SCAN             | XPKCUSTOMERS         |     1 |     4 |     0   (0)| 00:00:01 |
|  18 |    TABLE ACCESS FULL              | VM_COMPUTE_HISTORIES |  5769 | 51921 |    15   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------

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

   2 - access("C"."VM_ID"="F"."VM_ID")
   4 - access("C"."VM_GROUP_ID"="B"."VM_GROUP_ID")
   7 - access(ROWID=ROWID)
  10 - access("C"."VM_ID"="D"."VM_ID")
  14 - access("D"."LICENSE_ID"="E"."LICENSE_ID")
       filter("D"."LICENSE_ID"="E"."LICENSE_ID")
  17 - access("A"."CUSTOMER_ID"="B"."CUSTOMER_ID")

36 rows selected.

SQL> 

2 个答案:

答案 0 :(得分:2)

试试这个,它可能会加快你的查询速度

SELECT /*+ use_hash(a,b,c,d,e,f) */

在查询中使用此SELECT语句。

答案 1 :(得分:1)

尝试将解释计划与此SQL进行比较。我无法将其粘贴为评论,因此我必须将其作为"回答"发布。我从你的查询中注意到的是你从不投射表格中的值" b"所以EXISTS可能有助于使事情变得更快......

检查出来:

  SELECT a.customer_id,
         c.vm_mor,
         c.vm_id,
         d.license_id,
         e.product,
         f.guest_os_id
    FROM customers a,
         vms c,
         vm_licenses d,
         licenses e,
         vm_compute_histories f
   WHERE     EXISTS
                 (SELECT 'X'
                    FROM vm_groups vm1
                   WHERE     a.customer_id = vm.customer_id
                         AND c.vm_group_id = vm.vm_group_id)
         AND c.vm_id = d.vm_id
         AND d.license_id = e.license_id
         AND c.vm_id = f.vm_id
ORDER BY a.customer_id, vm_id