1. 程式人生 > >Oracle優化——星型聯結轉換(star_transformation_enabled)

Oracle優化——星型聯結轉換(star_transformation_enabled)

參見 Oracle效能優化求生指南。

另外請了解點陣圖聯結索引,此類問題的最佳實踐。

這是一個星型聯結的例子,sales為事實表,其它為維度表。Where條件全部都作用在維度表上面。
[email protected] prod> select quantity_sold , amount_sold from sales s join products p using ( prod_id )
  2  join times using ( time_id ) join customers c using ( cust_id )
  3  where week_ending_day = '29-Nov-2008' 
  4  and prod_name = '1.44MB External 3.5'' Diskette' 
  5  and cust_year_of_birth = 1965 ;

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 3891315047

--------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                             | Name             | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                      |                  |     1 |    80 |    30   (0)| 00:00:01 |       |       |
|   1 |  NESTED LOOPS                         |                  |       |       |            |          |       |       |
|   2 |   NESTED LOOPS                        |                  |     1 |    80 |    30   (0)| 00:00:01 |       |       |
|   3 |    NESTED LOOPS                       |                  |     4 |   284 |    26   (0)| 00:00:01 |       |       |
|   4 |     MERGE JOIN CARTESIAN              |                  |     1 |    46 |    21   (0)| 00:00:01 |       |       |
|*  5 |      TABLE ACCESS FULL                | TIMES            |     1 |    16 |    18   (0)| 00:00:01 |       |       |
|   6 |      BUFFER SORT                      |                  |     1 |    30 |     3   (0)| 00:00:01 |       |       |
|*  7 |       TABLE ACCESS FULL               | PRODUCTS         |     1 |    30 |     3   (0)| 00:00:01 |       |       |
|   8 |     TABLE ACCESS BY GLOBAL INDEX ROWID| SALES            |     9 |   225 |     5   (0)| 00:00:01 | ROWID | ROWID |
|*  9 |      INDEX RANGE SCAN                 | SALES_CONCAT_IDX |     9 |       |     2   (0)| 00:00:01 |       |       |
|* 10 |    INDEX UNIQUE SCAN                  | CUSTOMERS_PK     |     1 |       |     0   (0)| 00:00:01 |       |       |
|* 11 |   TABLE ACCESS BY INDEX ROWID         | CUSTOMERS        |     1 |     9 |     1   (0)| 00:00:01 |       |       |
--------------------------------------------------------------------------------------------------------------------------

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

   5 - filter("TIMES"."WEEK_ENDING_DAY"=TO_DATE(' 2008-11-29 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
   7 - filter("P"."PROD_NAME"='1.44MB External 3.5'' Diskette')
   9 - access("S"."PROD_ID"="P"."PROD_ID" AND "S"."TIME_ID"="TIMES"."TIME_ID")
  10 - access("S"."CUST_ID"="C"."CUST_ID")
  11 - filter("C"."CUST_YEAR_OF_BIRTH"=1965)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
         56  consistent gets
          0  physical reads
          0  redo size
        414  bytes sent via SQL*Net to client
        512  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
0rows processed
執行計劃中用到了笛卡爾聯結。

其實上面的查詢等效於下面的(連執行計劃都是一樣的):
[email protected]
prod> select quantity_sold , amount_sold from sales s 2 where s.prod_id in ( select prod_id from products where prod_name = '1.44MB External 3.5" Diskette' ) 3 and s.time_id in ( select time_id from times where week_ending_day = '29-Nov-2008' ) 4 and s.cust_id in ( select cust_id from customers where cust_year_of_birth = 1965 ) ; no rows selected Execution Plan ---------------------------------------------------------- Plan hash value: 3891315047 -------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | -------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 80 | 30 (0)| 00:00:01 | | | | 1 | NESTED LOOPS | | | | | | | | | 2 | NESTED LOOPS | | 1 | 80 | 30 (0)| 00:00:01 | | | | 3 | NESTED LOOPS | | 4 | 284 | 26 (0)| 00:00:01 | | | | 4 | MERGE JOIN CARTESIAN | | 1 | 46 | 21 (0)| 00:00:01 | | | |* 5 | TABLE ACCESS FULL | TIMES | 1 | 16 | 18 (0)| 00:00:01 | | | | 6 | BUFFER SORT | | 1 | 30 | 3 (0)| 00:00:01 | | | |* 7 | TABLE ACCESS FULL | PRODUCTS | 1 | 30 | 3 (0)| 00:00:01 | | | | 8 | TABLE ACCESS BY GLOBAL INDEX ROWID| SALES | 9 | 225 | 5 (0)| 00:00:01 | ROWID | ROWID | |* 9 | INDEX RANGE SCAN | SALES_CONCAT_IDX | 9 | | 2 (0)| 00:00:01 | | | |* 10 | INDEX UNIQUE SCAN | CUSTOMERS_PK | 1 | | 0 (0)| 00:00:01 | | | |* 11 | TABLE ACCESS BY INDEX ROWID | CUSTOMERS | 1 | 9 | 1 (0)| 00:00:01 | | | -------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 5 - filter("WEEK_ENDING_DAY"=TO_DATE(' 2008-11-29 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) 7 - filter("PROD_NAME"='1.44MB External 3.5" Diskette') 9 - access("S"."PROD_ID"="PROD_ID" AND "S"."TIME_ID"="TIME_ID") 10 - access("S"."CUST_ID"="CUST_ID") 11 - filter("CUST_YEAR_OF_BIRTH"=1965) Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 56 consistent gets 0 physical reads 0 redo size 414 bytes sent via SQL*Net to client 512 bytes received via SQL*Net from client 1 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 0 rows processed 使能星型聯結轉換(注意,星型聯結轉換預設不是使能的)
[email protected]
prod> alter session set star_transformation_enabled = true ; Session altered. 再看兩個表的執行計劃,其實還是一樣的,只不過更多的使用了點陣圖合併。這需要在事實表的每個外來鍵上新增點陣圖索引。 這種叫做星型轉換,一般用在資料倉庫中。 [email protected] prod> select quantity_sold , amount_sold from sales s 2 where s.prod_id in ( select prod_id from products where prod_name = '1.44MB External 3.5" Diskette' ) 3 and s.time_id in ( select time_id from times where week_ending_day = '29-Nov-2008' ) 4 and s.cust_id in ( select cust_id from customers where cust_year_of_birth = 1965 ) ; no rows selected Execution Plan ---------------------------------------------------------- Plan hash value: 3061144765 ----------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | ----------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 34 | 53 (0)| 00:00:01 | | | | 1 | NESTED LOOPS | | | | | | | | | 2 | NESTED LOOPS | | 1 | 34 | 32 (0)| 00:00:01 | | | | 3 | PARTITION RANGE SUBQUERY | | 8 | 218 | 23 (0)| 00:00:01 |KEY(SQ)|KEY(SQ)| | 4 | TABLE ACCESS BY LOCAL INDEX ROWID| SALES | 8 | 218 | 23 (0)| 00:00:01 |KEY(SQ)|KEY(SQ)| | 5 | BITMAP CONVERSION TO ROWIDS | | | | | | | | | 6 | BITMAP AND | | | | | | | | | 7 | BITMAP MERGE | | | | | | | | | 8 | BITMAP KEY ITERATION | | | | | | | | | 9 | BUFFER SORT | | | | | | | | |* 10 | TABLE ACCESS FULL | TIMES | 1 | 16 | 18 (0)| 00:00:01 | | | |* 11 | BITMAP INDEX RANGE SCAN | SALES_TIME_BIX | | | | |KEY(SQ)|KEY(SQ)| | 12 | BITMAP MERGE | | | | | | | | | 13 | BITMAP KEY ITERATION | | | | | | | | | 14 | BUFFER SORT | | | | | | | | |* 15 | TABLE ACCESS FULL | PRODUCTS | 1 | 30 | 3 (0)| 00:00:01 | | | |* 16 | BITMAP INDEX RANGE SCAN | SALES_PROD_BIX | | | | |KEY(SQ)|KEY(SQ)| |* 17 | INDEX UNIQUE SCAN | CUSTOMERS_PK | 1 | | 0 (0)| 00:00:01 | | | |* 18 | TABLE ACCESS BY INDEX ROWID | CUSTOMERS | 1 | 9 | 1 (0)| 00:00:01 | | | ----------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 10 - filter("WEEK_ENDING_DAY"=TO_DATE(' 2008-11-29 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) 11 - access("S"."TIME_ID"="TIME_ID") 15 - filter("PROD_NAME"='1.44MB External 3.5" Diskette') 16 - access("S"."PROD_ID"="PROD_ID") 17 - access("S"."CUST_ID"="CUST_ID") 18 - filter("CUST_YEAR_OF_BIRTH"=1965) Note ----- - star transformation used for this statement Statistics ---------------------------------------------------------- 5 recursive calls 0 db block gets 56 consistent gets 0 physical reads 0 redo size 414 bytes sent via SQL*Net to client 512 bytes received via SQL*Net from client 1 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 0 rows processed
[email protected]
prod> select quantity_sold , amount_sold from sales s join products p using ( prod_id ) 2 join times using ( time_id ) join customers c using ( cust_id ) 3 where week_ending_day = '29-Nov-2008' 4 and prod_name = '1.44MB External 3.5'' Diskette' 5 and cust_year_of_birth = 1965 ; no rows selected Execution Plan ---------------------------------------------------------- Plan hash value: 3061144765 ----------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | ----------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 34 | 53 (0)| 00:00:01 | | | | 1 | NESTED LOOPS | | | | | | | | | 2 | NESTED LOOPS | | 1 | 34 | 32 (0)| 00:00:01 | | | | 3 | PARTITION RANGE SUBQUERY | | 8 | 218 | 23 (0)| 00:00:01 |KEY(SQ)|KEY(SQ)| | 4 | TABLE ACCESS BY LOCAL INDEX ROWID| SALES | 8 | 218 | 23 (0)| 00:00:01 |KEY(SQ)|KEY(SQ)| | 5 | BITMAP CONVERSION TO ROWIDS | | | | | | | | | 6 | BITMAP AND | | | | | | | | | 7 | BITMAP MERGE | | | | | | | | | 8 | BITMAP KEY ITERATION | | | | | | | | | 9 | BUFFER SORT | | | | | | | | |* 10 | TABLE ACCESS FULL | TIMES | 1 | 16 | 18 (0)| 00:00:01 | | | |* 11 | BITMAP INDEX RANGE SCAN | SALES_TIME_BIX | | | | |KEY(SQ)|KEY(SQ)| | 12 | BITMAP MERGE | | | | | | | | | 13 | BITMAP KEY ITERATION | | | | | | | | | 14 | BUFFER SORT | | | | | | | | |* 15 | TABLE ACCESS FULL | PRODUCTS | 1 | 30 | 3 (0)| 00:00:01 | | | |* 16 | BITMAP INDEX RANGE SCAN | SALES_PROD_BIX | | | | |KEY(SQ)|KEY(SQ)| |* 17 | INDEX UNIQUE SCAN | CUSTOMERS_PK | 1 | | 0 (0)| 00:00:01 | | | |* 18 | TABLE ACCESS BY INDEX ROWID | CUSTOMERS | 1 | 9 | 1 (0)| 00:00:01 | | | ----------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 10 - filter("TIMES"."WEEK_ENDING_DAY"=TO_DATE(' 2008-11-29 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) 11 - access("S"."TIME_ID"="TIMES"."TIME_ID") 15 - filter("P"."PROD_NAME"='1.44MB External 3.5'' Diskette') 16 - access("S"."PROD_ID"="P"."PROD_ID") 17 - access("S"."CUST_ID"="C"."CUST_ID") 18 - filter("C"."CUST_YEAR_OF_BIRTH"=1965) Note ----- - star transformation used for this statement Statistics ---------------------------------------------------------- 4 recursive calls 0 db block gets 56 consistent gets 0 physical reads 0 redo size 414 bytes sent via SQL*Net to client 512 bytes received via SQL*Net from client 1 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 0 rows processed


相關推薦

Oracle優化——聯結轉換star_transformation_enabled

參見 Oracle效能優化求生指南。 另外請了解點陣圖聯結索引,此類問題的最佳實踐。 這是一個星型聯結的例子,sales為事實表,其它為維度表。Where條件全部都作用在維度表上面。 [email protected] prod> select quant

ORACLE』 DG性能轉換11g

files bsp 備庫 for ima -s rim line 修改 一、最大性能轉換至最大可用 確認主庫模式: [email protected]/* */ hey~2->select protection_mode,protection_level

Oracle優化器之基數反饋CardinalityFeedback功能

概述 在Oracle 11gR2的版本上推出了基數反饋(Cardinality Feedback 以後簡稱CFB)功能,通過這個特性,對於某些查詢在第一次執行時,如果CBO發現根據統計資訊估算出的基數(Computed cardinality)和SQL執行時的實際值差距很大的情況

z字串轉換演算法

<?php header("Content-type:text/html;charset=utf-8"); /** * 處理最小週期內的字串 * @author syh * @para

C之類轉換

C語言 強制類型轉換 隱式類型轉換 我們知道在 C 語言中有時會需要進行類型的轉換,這個轉換分為兩種。一種是強制類型轉換,如:short s = 2; int i = (int)s; 還有一種就是隱式類型轉換,如:short s = 5; int i = s;

新型的類轉換

C++ static_cast const_cast reinterpret_cast dynamic_cast 我們之前在 C 語言進行類型轉換是強制類型轉換的,這樣極易出 bug,還不易查找。格式如下:(Type)(Experssion) 或 Type(Experssi

實體類轉換ConvertObject

urn init map des mar rto create 對象 ret /// <summary> /// 單個對象轉換 /// </summary> /// <typeparam name="

網絡傳輸中利用fastjson將復雜嵌套數據類Json格式轉換GeoJsonPolygon

bsp ejs style post 數據表 strong 註意 ets beans 如果一個對象太復雜了,那麽在網絡傳輸鍵的JSON格式數據轉換容易出問題。 比如下面一個類Area.java import lombok.AllArgsConstructor; impor

資料倉庫結構設計結構和雪花結構

當有一個或多個維表沒有直接連線到事實表上,而是通過其他維表連線到事實表上時,其圖解就像多個雪花連線在一起,故稱雪花模型。雪花模型是對星型模型的擴充套件。它對星型模型的維表進一步層次化,原有的各維表可能被擴充套件為小的事實表,形成一些區域性的 " 層次 " 區域,這些被分解的表都連線到主維度表而不是事實表。如圖

Oracle之SQL優化-索引的基本原理

導讀:1、為什麼使用索引? 2、什麼情況下適合建立索引? 3、建立索引的策略。 4、如何對索引進行操作。 5、常用到的一些索引操作。 1、為什麼使用索引? (1)、原因   索引中只有一列,io小,所以較快;   索引中此列是排序的,二叉查詢,提高查詢速度。 (2)、原因分

Key-Value別的RDD的建立及基本轉換1

1. 建立一個基本的key-value的RDDscala> val kvPairRDD =      |   sc.parallelize(Seq(("key1", "value1"), ("key2", "value2"), ("key3", "value3")))

Oracle】 sql 中的字元替換與轉換

1、REPLACE 語法:REPLACE(char, search_string,replacement_string) 用法:將char中的字串search_string全部轉換為字串replacement_string。         舉例:SQL> se

數據類轉換3種情況

mage bsp define afa false strong 結果 ont 引用 JS中類型轉換只有三種情況,分別是 轉換為布爾值 【 Boolean()】 轉換為數字 【 Number()、parseInt()、parseFalse() 】 轉換為字符串【 Str

C語言數據類轉換隱式轉換

箭頭 long 一起 系統 結果 註意 數據轉換 表示 轉換 算術運算符中的轉換規則:double ←── float 高↑long↑unsigned↑int ←── char,short 低註意:   圖中橫向箭頭表示必

JavaScript 類轉換2

隱式 -- 變量 依然 undefine 轉換成 === 也會 一個 隱式類型轉換 1.   var a = "123"; a++;   這時候會將調用Number("123")將"123"轉換成數字類型,然後再自增。 var a = "abc";

懶要懶到底,能自動的就不要手動,Hibernate正向工程完成Oracle資料庫到MySql資料庫轉換含欄位轉換、註釋

需求描述 需求是這樣的:因為我們目前的一個老專案是Oracle資料庫的,這個庫呢,資料庫是沒有註釋的,而且欄位名和表名都是大寫風格,比如 在程式碼層面的po呢,以前也是沒有任何註釋的,但是經過這些年,大家慢慢踩坑多了,也給po加上了一些註釋了,比如: 現狀就是這樣,再說說目標是:希望把這個庫能轉成my

ORACLE』 PLSQL條件控制語句11g

lin proc lar plsql 判斷語句 條件 num success end 簡單條件判斷語句 SQL> declare 2 myage number := 10; 3 begin 4 if myage < 11 then 5 dbms

ORACLE』 PLSQL遊標的使用11g

not blog 技術分享 當前 rac let 使用 png log 遊標分類 隱式遊標: 對於select..into...語句,一次只能從數據庫中獲取到一條數據,對於這種類型的DML SQL語句,就是隱式cursor select update

ORACLE』 設置Edit模式11g

配置 修改 sqlplus spa size span -s ont def SQL>define_editor=‘vi‘ 執行一條SQL語句再修改編輯 SQL>ed 可以將define _editor=‘vi‘這句話寫在sqlplus 的啟動配置腳本中『ORA

C#基礎知識-引用類和值類的區別

值類型 type 調用 執行 new 內存堆 ada ont 不同類 在第一篇中我們介紹了C#中基本的15種數據類型,這15種數據類型中又分為兩大類,一種是值類型,一種是引用類型。值類型有sbyte、short、long、int、byte、ushort、uint、u