2016년 12월 14일 수요일

[자바교육,스프링교육,JPA교육학원_탑크리에듀][스프링JPA강좌,실습]1대1 단방향 식별관계, 대상테이블에 외래키, @OneToOne, @MapsId, @JoinColumn,엔티티매핑

[스프링JPA강좌,실습]1단방향 식별관계대상테이블에 외래키, @OneToOne, @MapsId, @JoinColumn,엔티티매핑

n  주테이블의 PK가 자식테이블에 식별자(PK) 형태로 외래키로 내려가는 경우이며부모테이블의 기본키를 자식 테이블에서도 기본키로 사용하는 경우이다.
자식테이블의 기본키로는 부모테이블에서 내려오는 외래키만을 사용하고식별자가 하나인 경우에는 @MapsId를 사용한다.

첨부 파일 참조 하세요.
감사합니다.

첨부파일 URL참조 - http://ojc.asia/bbs/board.php?bo_table=LecJpa&wr_id=211

[자바교육,스프링교육,JPA교육학원_탑크리에듀][스프링JPA강좌]1 : 1 단방향, 대상테이블에 외래키(JPA 1.0, JPA2.0),@OneToOne연관관계,엔티티매핑

[스프링JPA강좌]1 : 1 단방향, 대상테이블에 외래키(JPA 1.0, JPA2.0),@OneToOne연관관계,엔티티매핑

첨부 파일 참조 부탁 드립니다.
감사합니다.

첨부파일 URL참조 - http://ojc.asia/bbs/board.php?bo_table=LecJpa&wr_id=210

2016년 12월 13일 화요일

[오라클교육,튜닝교육,SQL교육학원추천_탑크리에듀][SQL튜닝]OR연산을 Union으로...

[SQL튜닝]OR연산을 Union으로... 

아래 쿼리를 이해하자. 

-- myemp1, myemp_old 테이블은 같은 구조를 가지며, 
-- myemp1 : 2000만건, myemp1_old : 300만건 
-- ename, sal 칼럼에 대해 각각 인덱스가 생성되어 있다. 

-- 6.5초 
SELECT e1.ename FROM myemp1 e1, myemp1_old e2 
WHERE e1.ename = e2.ename 
OR e1.sal = e2.sal 


-- 아래 쿼리가 조금 빠르다. 
-- 6.0초 
SELECT e1.ename FROM myemp1 e1, myemp1_old e2 
WHERE e1.ename = e2.ename 
union all 
SELECT e1.ename FROM myemp1 e1, myemp1_old e2 
WHERE e1.sal = e2.sal 

인덱스가 생성된 칼럼에 대해 or 로 WHERE절을 사용하는 경우 union all을 사용하는것이 조금 빠르다.

[오라클교육,튜닝교육,SQL교육학원추천_탑크리에듀][SQL,COUNT]분포도가 좋지않은 컬럼(B*Tree인덱스)의 count연산시 index fast full scan과 index range scan의 성능 차이 비교

[SQL,COUNT]분포도가 좋지않은 컬럼(B*Tree인덱스)의 count연산시 index fast full scan과 index range scan의 성능 차이 비교 

아래 테스트를 보시면 알겠지만 비트리 인덱스인 경우 분포도가 좋지 않은 컬럼을 count하는 경우라면 
index fast full scan보다 index range scan이 좋을 것 같습니다. 

아래 결과 확인해 주세요~ 

myemp1 테이블의 성별(sungbyul) 칼럼은 'M' or 'F' 값을 가지며 값의 분포도는 50% 이다. 

desc myemp1 
이름      널        유형            
-------- -------- ------------- 
EMPNO    NOT NULL NUMBER        
ENAME            VARCHAR2(100) 
DEPTNO            VARCHAR2(1)  
ADDR              VARCHAR2(100) 
SAL              NUMBER        
SUNGBYUL          VARCHAR2(1) 

-- 비트리 인덱스를 만들자. 
create index idx_myemp1_sungbyul on myemp1(SUNGBYUL) 

1. CBO MODE에서 COUNT를 하면 기본적으로 index fast full 스캔을 한다. 
(수행시간 : 2초) 

SQL> alter session set optimizer_mode = all_rows; 

SQL> select count(*) from myemp1 where sungbyul = 'M'; 

  COUNT(*) 
---------- 
  12000000 

경  과: 00:00:02.03 

Execution Plan 
---------------------------------------------------------- 
Plan hash value: 977383106 
---------------------------------------------------------- 
| Id  | Operation            | Name                | Rows  | Bytes | Cost (%CPU 
-------------------------------------------------------------------------------- 
|  0 | SELECT STATEMENT      |                    |    1 |    2 |  9995  (2 
|  1 |  SORT AGGREGATE      |                    |    1 |    2 | 
|*  2 |  INDEX FAST FULL SCAN| IDX_MYEMP1_SUNGBYUL |    10M|    19M|  9995  (2 
-------------------------------------------------------------------------------- 


2. RBO MODE에서 COUNT를 하면 기본적으로 index range 스캔을 한다. 
(수행시간 : 0초) 

SQL> alter session set optimizer_mode = rule; 
SQL> select count(*) from myemp1 where sungbyul = 'M'; 

  COUNT(*) 
---------- 
  12000000 

경  과: 00:00:00.70 

Execution Plan 
---------------------------------------------------------- 
Plan hash value: 1101074595 

------------------------------------------------- 
| Id  | Operation        | Name                | 
------------------------------------------------- 
|  0 | SELECT STATEMENT  |                    | 
|  1 |  SORT AGGREGATE  |                    | 
|*  2 |  INDEX RANGE SCAN| IDX_MYEMP1_SUNGBYUL | 
-------------------------------------------- 


3. 아래처럼 CBO 모드라면 index 힌트를 사용해도 된다. 

SQL> select /*+ index(myemp1 idx_myemp1_sungbyul) */  count(*) from myemp1 where sungbyul = 'M'; 

  COUNT(*) 
---------- 
  10000002 

경  과: 00:00:00.75 

Execution Plan 
---------------------------------------------------------- 
|  0 | SELECT STATEMENT  |                    |    1 |    1 | 18223  (1)| 0 
|  1 |  SORT AGGREGATE  |                    |    1 |    1 |            | 
|*  2 |  INDEX RANGE SCAN| IDX_MYEMP1_SUNGBYUL |    10M|  9765K| 18223  (1)| 0

[오라클교육,튜닝교육,SQL교육학원추천_탑크리에듀][ORACLE SQL]count와 구체화뷰(materialized view in SQL count function),ORA-12034

[ORACLE SQL]count와 구체화뷰(materialized view in  SQL count function),ORA-12034 


SQL count(*)연산의 성능 


myemp1 테이블의 건수는 2000만건, PK는 empno 


PK 인덱의 이름은 다음과 같다. 


select index_name  from user_indexes  where table_name = 'MYEMP1' 
==> SYS_C0011116 


SQL> desc myemp1 
        
-------- -------- ------------- 
EMPNO    NOT NULL NUMBER 
ENAME          VARCHAR2(100) 
DEPTNO          VARCHAR2(1) 
ADDR          VARCHAR2(100) 
SAL          NUMBER 
SUNGBYUL          VARCHAR2(1) 


-- 5초 
select count(*) from myemp1 e 


------------------------------------------------------------------------------ 
|  0 | SELECT STATEMENT      |              |    1 | 10832  (2)| 00:02:10 | 
|  1 |  SORT AGGREGATE      |              |    1 |            |          | 
|  2 |  INDEX FAST FULL SCAN| SYS_C0011116 |    20M| 10832  (2)| 00:02:10 | 
------------------------------------------------------------------------------ 


CBO모드에서는 아래와 같은 결과다. 
-- 2초 
select /*+ index_ffs(e SYS_C0011116)  */ count(*) 
from myemp1 e 
where empno > 0 


대부분 count연산은 CBO에서 index fast full scan 한다. 




이번에는 index 힌트를 사용해보자. 


--1.5초 
select /*+ index(e SYS_C0011116)  */ count(*) 
from myemp1 e 
where empno > 0 


이번에는 구체화 뷰를 이용하자. 


1. MVIEW LOG 생성(count, sum등 사용시 리얼타임으로 mview쪽 갱신을 위해 필요) 


DROP MATERIALIZED VIEW LOG ON myemp1; 
CREATE MATERIALIZED VIEW LOG ON myemp1 WITH PRIMARY KEY, ROWID 
INCLUDING NEW VALUES 


2. mview 생성 


DROP MATERIALIZED VIEW myemp1_count 


CREATE MATERIALIZED VIEW myemp1_count 
BUILD IMMEDIATE -- MView 생성과 동시에 데이터들도 생성 
REFRESH FAST -- 원본의변경된 데이터만 mview에 갱신 
ON COMMIT -- Commit 이 일어날 때 뷰 Refresh 
ENABLE QUERY REWRITE 
AS 
select count(*) cnt from myemp1 


count 해보자. 


-- 0초 
select count(*) from myemp1 


-------------------------------------------------------------------------------- 
|  0 | SELECT STATEMENT            |              |    1 |    13 |    3  (0 
|  1 |  MAT_VIEW REWRITE ACCESS FULL| MYEMP1_COUNT |    1 |    13 |    3  (0 
-------------------------------------------------------------------------------- 


3. myemp1 테이블에 데이터 한건 삽입하고 mview쪽이 갱신되는지 확인하자. 


insert into myemp1(empno, ename) values (20000001, '2001길동')

[오라클교육,튜닝교육,SQL교육학원추천_탑크리에듀][오라클SQL실행처리순서]SQL문장(SELECT)의 처리과정

[오라클SQL실행처리순서]SQL문장(SELECT)의 처리과정(파싱, 옵티마이저, FETCH, 실행, Library Cache, Parse-Tree, Query Transformer, Estimator, Plan Generator)

사용자가 SQL문장(select)을 실행
- 오라클 서버측 리스너가 서버 프로세스로 SQL문장을 전달

 
SQL 파싱
 
- 서버프로세스는 Shared Pool의 Library Cache를 조회해서 동일한 SQL문장이 있는지 확인하는데 문자 하나하나 공백, 대소문자까지 비교하여 이미 있다면 Library Cache의 parse-tree와 Query Execution Plan을 가지고 와서 실행한다. 이를 Soft Parsing 이라하고
 
없다면 먼저 사용자 SQL 문장의 문법체크(Syntax Check)를 우선 진행하고, 데이블 및 컬럼이 있는지, 해당 USER가  데이블 및 컬럼을 SELECT할 권한이 있는지(Semantic Check)를 Data Dictionary를 통해 체크하는데 이후 parse-tree를 만들고 나중을 위해 Library Cache에 저장한다.

Syntax, Semantic 체크를 모두 통과하였다면 이 SQL 구문은 오류가 없는 문장이 되며 해당 문장에 해싱 알고리즘을 적용하여, SQL커서가 메모리상에 존재하고 있는지를 체크한다. SQL구문을 보낸 사용자나 옵티마이저 MODE관련 설정까지 일치하는 SQL커서가 존재하고 있다면 더이상 추가 작업 없이 그 SQL 정보를 이용하게되며 이를 소프트 파싱이라 부른다

- SQL커서가 없다면 Parsing된 SQL문장(쿼리 블럭의 set)을 Optimizer(Query Transformer, Estimator, Plan Generator)로 전달
 
SQL 최적화 - Optimizer
 
- Query Transformer : 쿼리블록으로 나누어 변형된 몇 종류의 쿼리문을 생산, 
                             서브쿼리를 조인으로 변경한다든지, 뷰의 해체작업, 인라인뷰의 해체작업, 
                             FROM절의 테이블제거작업등을 거쳐 쿼리를 변형한다.

- Estimator : 주어진 SQL문장의 모든 Cost를 측정한다. Selectivity(선택도) , Cardinality, Cost등 세가지 다른 측정방법을 이용하며 최소의 비용을 갖는 SQL문장을 Plan Generator에게 넘긴다.     
          
- Plan Generator : 선택된 저비용 SQL문의 실행계획을 생성하여 Row Source Generator에게 넘긴다. 이렇게 생성한 실행계획도 나중을 위해 Library Cache에 저장해 둔다.

실행(Execution)
 
- Row Source Generator : 실행계획의  각단계를 실행
                                 DataBase Buffer Cache 영역에서 논리적읽기와 물리적 읽기를 실행
                                 DataBase Buffer Cache에 free영역이 존재하지 않으면 LRU 알고리즘에 의해 공간확보
                                 버퍼캐시에 없다면 디스크의 DataFile을 읽어 데이터 버퍼 캐시에 적재

추출(Fetch)

- 서버 프로세스가 DataBase Buffer Cache에 저장된 데이터를 읽어 User Process에게 결과를 넘겨준다.  (DML인 경우에는 수행하지 않는다.)

[오라클교육,튜닝교육,SQL교육학원추천_탑크리에듀][오라클11g에서 비트맵인덱스를 이용한 count, or 연산 튜닝, oracle bitmap index SQL tuning]

[오라클11g에서 비트맵인덱스를 이용한 count, or 연산 튜닝, oracle bitmap index SQL tuning] 

oracle 11g에서... 

myemp1 테이블의 구조는 다음과 같다. 
SQL> desc myemp1 
 이름                                      널?      유형 
 ----------------------------------------- -------- ------------------- 
 EMPNO                                    NOT NULL NUMBER 
 ENAME                                              VARCHAR2(100) 
 DEPTNO                                            VARCHAR2(1) 
 ADDR                                              VARCHAR2(100) 
 SAL                                                NUMBER 
 SUNGBYUL                                          VARCHAR2(1) 

데이터는 2000만건 정도 있으며, 현재 인덱스는 없다. 

-- 10여초 이상 
select count(*) from myemp1 
-- 이것도 10여초 이상 
select count(*) from myemp1 
where deptno = 1 
  or deptno = 4 

1. b*tree 인덱스 생성 
create index idx_myemp1_deptno on myemp1(deptno) 

--8.9초(index fast full scan) 
select count(deptno) from myemp1 
where deptno = 1 
  or deptno = 4 
  
-- 16초  
select count(*) from myemp1 
where deptno = 1 
  or deptno = 4 
  
-- 9초정도 index fast full scan 
select /*+ index_ffs(myemp1 idx_myemp1_deptno) */ count(deptno) from myemp1 
where deptno = 1 
  or deptno = 4    
  

2. bitmap 인덱스 생성 
create bitmap index idx_myemp1_deptno on myemp1(deptno) 

--0초(비트맵인덱스 이용) 
select count(deptno) from myemp1 
where deptno = 1 
  or deptno = 4 
  
  
select count(*) from myemp1 
쿼리역시 비트맵 인덱스를 이용하여 0초 

물론 비트맵 인덱스가 이러한 장점만 있는것은 아니다. DML이 발생하면 
같은 값을 가지는 모든 레코드에 락이 걸린다는점 유념하자.