1장. 인덱스의 원리와 활용


(1) 인덱스의 구조

  - 인덱스 키 컬럼 + rowid 

  -  null 값에는 index가 생성 되지 않는다.
  -  인덱스의 구조를 보고 싶은데 where 절에 적절하게 이용할 조건이 없다면 ?
    (인덱스를 통하려면 무조건 where 절에 해당 인덱스 컬럼이 존재해야 한다.)
    1) 숫자 > 0
    2) 문자 > ' '
    3) where ename < to_date('9999/12/31','RRRR/MM/DD')

 * 해당 index에서 ename is not null 로 걸면 index full table scan 이 된다.
 
(2) index를 사용하지 못하는 경우
   1) 인덱스 컬럼이 가공이 되면 인덱스 엑세스가 안된다.
       ( where 조건절에 인덱스 컬럼이 가공이 되면 정상적으로 인덱스를 엑세스 할 수 없다.)
  
         - 명시적 형변환
         - 묵시적(암시적) 형변환 
               - 숫자가 우선 순위에 있다.
               - 비교하는값이 문자라면 컬럼 값이 숫자여도 문자로 변환된다.     
               - 묵시적 형변환으로 인하여 함수 기반 인덱스를 생성할 경우도 있다.
                 (그러나 그렇게 추천할 만한 사항은 아니다.)  

     2) 부정형 비교시

       * 오라클 옵티마이저가 제대로 작동하지 않는다면 ( 정렬시 컬럼 값이 정렬되어 있지 않다면) SQL 문에 힌트를 사용한다.
          (힌트 (hint) - 실행계획에 영향을 미치는 명령어)
       * 와일드 카드를 앞에 사용하면 index range scan 이 안된다.

(3) 다양한 인덱스 스캔 방식

     1) Data를 엑세스 하는 방법
            ⑴ 테이블 엑세스 방법
                - rowid 에 의한 data 검색
                - full table scan
        
           ⑵ 인덱스 엑세스 방법
                - index range scan
                - index full scan
                - index unique scan
                - index skip scan
                - index fast full scan
                - index merge scan
                - index bitmap merge scan
                - index join

    2) rowid 에 의한  data 검색
         - 하나의 row를 검색하는 가장 빠른 방법

            ⑴ rowid란
                - row의 물리적 주소 (file#+block#+row#)

            ⑵ rowid hint

              - /*+ rowid(테이블명) */

            예시)
              SELECT ename ,sal
                FROM EMP
             WHERE ROWID = 'AAASlIAAEAAAALuAAL';


 * SQL_실행계획 읽는 법

---------------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |     2 |    40 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP     |     2 |    40 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | EMP_SAL |     2 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
  -> 가장 안 쪽으로 들어가 있는 부분부터 읽으면서 위로 올라간다.


문제 1. 부서번호의 인덱스를 생성하고 부서번호에 인덱스의 구조를 확인하시오!

SQL> create index emp_deptno
            on emp(deptno) ;

SQL> select deptno, rowid
           from emp
         where deptno > 0 ;


문제 2. 아래의  SQL 의 실행계획을 확인해서 SQL을 처리할 때 테이블을 엑세스 하지 않고 인덱스만 엑세스 했다는 것을 확인하시오!

SQL> select deptno, rowid
          from emp
       where deptno > 0 ;


문제 3. 사원 테이블에 월급에 인덱스르 걸고 월급에 걸린 인덱스의 구조를 확인 하시오 !

SQL> create index emp_sal
             on emp(sal) ;

SQL> select sal, rowid
          from emp
          where sal > 0;

* null 값에는 index가 생성 되지 않는다.


문제 4. 사원테이블에 ename 에 인덱스를 걸고 ename에 걸린 인덱스의 구조를 확인하시오!

SQL> create index emp_ename
             on emp(ename);

SQL> select ename, rowid
          from emp
         where  ename > ' ';

* 인덱스의 구조를 보고 싶은데 where 절에 적절하게 이용할 조건이 없다면 ?
    (인덱스를 통하려면 무조건 where 절에 해당 인덱스 컬럼이 존재해야 한다.)

1) 숫자 > 0
2) 문자 > ' '
3) where ename < to_date('9999/12/31','RRRR/MM/DD')

* 해당 index에서 ename is not null 로 걸면 index full table scan 이 걸린다.


문제 5. 입사일에 인덱스를 걸고 입사일에 걸린 인덱스의 구조를 확인하시오!

SQL> create index emp_hiredate
            on emp(hiredate) ;

SQL> SELECT /*+ index_asc(emp emp_hiredate) */ hiredate, rowid
            from emp
        WHERE hiredate < TO_DATE('9999/12/31','RRRR/MM/DD') ;

* 오라클 옵티마이저가 제대로 작동하지 않는다면 ( 정렬시 컬럼 값이 정렬되어 있지 않다면) SQL 문에 힌트를 사용한다.
* 힌트 (hint) - 실행계획에 영향을 미치는 명령어


문제 6. 월급이 1000에서 3000 사이인 사원들의 이름과 월급을 출력하는데 월급이 높은사원부터 출력하시오!

SQL> SELECT /*+ index_desc(emp emp_sal) */ ename, sal
            from emp
        WHERE sal BETWEEN 1000 AND 3000  ;

*  order by 절은 성능을 느리게 한다.
 

문제 7. 1981년도에 입사한 사원들의 이름과 입사일을 출력하는데 최근에 입사한 사원부터 출력하시오!

SQL> SELECT /*+ index_desc(emp emp_hiredate) */ ename,hiredate
        FROM emp
      WHERE hiredate between TO_DATE('1981/01/01','RRRR/MM/DD') AND TO_DATE('1981/12/31','RRRR/MM/DD');

* 위의 SQL이 Full table scan 이유
    - where  조건절에 인덱스 컬럼이 가공이 되면 정상적으로 인덱스를 엑세스 할 수 없다.


문제 8. 월급이 3000인 사원들의 이름과 월급을 출력하시오!

explain plan for
  SELECT ename, sal
  FROM emp
  WHERE sal=3000;

select * from table(dbms_xplan.display);


문제 9. 이름이 SCOTT 인 사원의 이름과 월급과 직업을 출력하는 실행계획을 출력하시오 !

SQL> explain plan for
    2   select ename, sal
    3  from emp
    4  where ename='SCOTT';

SQL> select * from table(dbms_xplan.display);


PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 106684950

-----------------------------------------------------------------------------------------
| Id  | Operation            | Name    | Rows    | Bytes | Cost (%CPU)| Time    |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |        |     1 |    20 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    20 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN        | EMP_ENAME |     1 |    |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------

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

   2 - access("ENAME"='SCOTT')

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


문제 10. 아래의 SQL 을 튜닝하시오 !

튜닝 전 :

select ename, sal *12 연봉
  from emp
where sal*12 =36000;

튜닝 후 :

SELECT /*index_desc(emp emp_sal)*/ename, sal*12 연봉
FROM EMP
WHERE sal = 36000/12;


문제 11. 아래의 SQL을 튜닝하시오!

create index emp_job
on emp(job);

튜닝 전 : 
select ename, job, sal
                from emp
              where substr(job,1,5)='SALES';

튜닝 후:
SELECT /*+ index(emp emp_job) */ ename, job, sal
  FROM EMP
  WHERE job LIKE 'SALES%' ;

※ 와일드 카드를 앞에 사용하면 index range scan 이 안된다.


문제 12. 아래의 데이터를 입력하고 오늘 입사한 사원의 이름과 입사일을 출력하시오!

SELECT ename, hiredate
FROM EMP
WHERE hiredate >= to_date('16/01/08','RR/MM/DD')
AND hiredate < TO_DATE('16/01/08','RR/MM/DD')+1;


문제 13. 아래의 SQL 을 튜닝하시오 !

- 조건
CREATE TABLE EMP700
  (ename VARCHAR2(20),
   SAL VARCHAR2(20));


CREATE INDEX emp700_sal
ON emp700(sal);


튜닝전 :

select ename, sal
from emp700
where sal = 3000;

* 위의 경우 실제 실행 방법

Plan hash value: 3880125747

----------------------------------------------------------------------------
| Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |        |       |       |     3 (100)|          |
|*  1 |  TABLE ACCESS FULL| EMP700 |     1 |    24 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------

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

   1 - filter(TO_NUMBER("SAL")=:SYS_B_0)

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

튜닝후:

SELECT /*+ index(emp700 emp700_sal) */ ename, sal
from emp700
where sal = '3000';

* SQL*plus 에서 실제 실행계획을 보는 명령어

-  select *
from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST +alias +outline +predicate'))
/


문제 14. 아래의 SQL의 결과가 출력되겠는가?

튜닝 전 :
select ename, sal
from emp
where sal like '30%';

* 해당 경우는 모델이 잘 못 된 경우로 해당 상태는 프로그램 수정으로는 튜닝이 안된다.
    So. 프로그램 수정이 아닌 다른 방법을 사용해야 한다. 

튜닝 후 : 
( 함수 기반 인덱스를 생성한다. )
create index emp_sal_func
on emp(to_char(sal));

select /*+ index(emp emp_sal_func) */ename, sal
from emp
where sal like '30%';

select /*+ index(emp emp_sal_func) */ename, sal  
from emp 
where sal like :"SYS_B_0"

( 바인드 변수 사용 )

Plan hash value: 3983152063

--------------------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |       |       |     4 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP          |    16 |   672 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | EMP_SAL_FUNC |    16 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

문제 15. 아래의 data를 입력하고 이름이  JANE 인 사원의 이름과 월급과 직업을 출력하시오!

튜닝 전:

insert into emp(empno, ename, sal)
valuse(2345, '   JANE  ', 4600);

튜닝 후

create index emp_ename_func
on emp(TRIM(ename));

SELECT /*+ index(emp emp_ename_func)*/ ename, sal, job
  FROM EMP
  WHERE TRIM(ename) = 'JANE';


문제 16. 이름이 EN 또는 IN을 포함하고 있는 사원들의 이름과 월급, 직업과 입사일을 출력하시오!

-- 튜닝 전

SELECT ename, sal, job, hiredate
FROM EMP
WHERE ename LIKE '%EN%'
or ename LIKE '%IN%';

OR

SELECT ename, sal, job, hiredate
FROM EMP
WHERE regexp_like(ename,'(EM|IN)');

-- 튜닝 후

SELECT ename, sal, job, hiredate
FROM EMP
WHERE ROWID in (SELECT /*+ index(emp emp_ename) */ rowid
                  from emp
                where ename like '%EN%' or ename like '%IN%') ;

or

SELECT /*+ no_query_transformation rowid(emp) */ ename, sal, job, hiredate
  FROM EMP e,(SELECT /*+ index(emp emp_ename)   */ rowid
                  from EMP
                where ename like '%EN%' or ename like '%IN%') b
WHERE e.ROWID = b.rowid  ;

* 둘의 실행 계획이 다르다. 
  - 바로 검색보다는 서브쿼리르 사용해서 rowid를 먼저 조회하고 검색하는 것이 빠를 수 있다.
  - 어떤 실행계획이 달라서 실행계획을 보고 계산할 수 있을 때까지는 어느것이 더 성능이 좋을 지 모른다.


1. 오라클 접속환경 2가지 

  1) two - tier 환경 

     client -------> database

  2) three - tier 환경 
   
     client ----------> Middle tier --------> database  
                      (로드 밸런싱 역활)

2. database 구성요소 

  1) data file - data가 들어있는 파일
   
      - 사용자 data ---> business data
      - 시스템 data ---> 시스템을 운영하기 위한 data

       * datafile 의 위치 확인하는 스크립트 
          - select file_name 
             from dba_data_files;
      
   2) control file - database의 구조정보가 들어있는 파일
         - 파일들의 위치와 이름, 상태정보 
        
       * controlfile의 위치 확인
        -  select name from v$controlfile;
            ( binary file ) 

       * text 용 controlfile을 생성하는 명령어
         
         SQL> alter database backup controlfile to trace as '/home/oracle/cre_control.sql';
    
    3) redo log file - 복구를 하기위해 필요한 파일
    
        * redo logfile의 위치를 확인하시오!
          SQL> select member
                   from v$logfile;
   
        * 메뉴얼에 나오는 ASM의 장점중 하나가 OS 엔지니어가 실수로 오라클의 파일을 삭제할 가능성이 낮아진다.
            - linux에서 rm 명령어로 삭제할 수 없다.

        * redo log 그룹이 몇개인지 확인하시오!
            SQL> select group#, status
                     from v$log;

    4) archive log file - redo logfile의 복사본

        * archive log file을 위치를 확인하는 명령어 
           - select name from v$archived_log;

       SQL> archive log list
               Database log mode              No Archive Mode
               Automatic archival             Disabled
               Archive destination            USE_DB_RECOVERY_FILE_DEST
               Oldest online log sequence     26
               Current log sequence             28

             - no archive mode : archive log file 을 사용하지 않는다. 

   * database mode를 archive log mode로 변경하는 방법
      1. SQL> archive log list                  <------ db 모드 확인
      2. SQL> shutdown immediate         <---- 정상종료
      3. SQL> startup mount                <----- mount 상태로 db를 올린다.
      4. SQL> alter database archivelog;   <----- 모드 변경 
      5. SQL> alter database open;           <---- mount에서 open으로 올린다. 
      6. SQL> archive log list                     <----- archive log list
 
     * archive log file은 switch log file 이 실행되면 생성된다. (default)
        (강제로 log를 스위치를 할 수 있다. ) 
 
     * 수동으로 로그 스위치하는 명령어 
      SQL> select group#, status from v$logfile;

      SQL> alter system swich logfile;

      SQL> select group#, status from v$logfile;

   

문제 1. 오라클 database 시스템의 구조 2가지 ?

답)  database , instance 
                         

문제 2. database 를 구성하는 파일들이 무엇이 있는가?

답) 1. data file - data가 들어있는 파일
     2. control file - database의 구조정보가 들어있는 파일
     3. redo log file - 복구를 하기위해 필요한 파일
     4. archive log file - redo logfile의 복사본
     5. password file - 특별한 권한을 가진 유저를 인증해주기 위한 파일
     6. parameter file  - 인스턴스의 구조정보가 들어있는 파일 


문제1. SQL의 종류에는 무엇이 있는가?
 
    (1) query (질의, 검색어)
         ~> select 문의 6가지 절

   (2) DML문 (Data manage Language)
        - insert /입력
        - update /수정
        - delete / 삭제
        - merge / 입력&수정&삭제
   
  (3) DDL문 (Data definition Language)
       - create /생성
       - alter /수정
       - drop /삭제
       - truncate /삭제
       - rename/이름 변경

  (4) DCL문 (Data control Language)
       - grant / 권한부여
       - revoke /권한취소
 
  (5) TCL문 (Transaction control Language)
       - commit / 변경된 내용을 영구히 저장
       - rollback /취소
       - savepoint /특정시점으로 취소
 

문제2. emp테이블 구조를 살펴보시오

SQL > describe emp

EMPNO      사원번호
ENAME      사원이름
JOB           직업
MGR          관리자의 사원번호
HIREDATE   입사일
SAL           월급
COMM       커미션
DEPTNO     부서번호



문제3. 이름과 월급을 출력하시오 !

SQL > select ename, sal  --- 컬럼명
          from emp;       --- 테이블 명

';' = 실행해 달라는 의미


문제4. 사원번호, 이름, 월급, 직업을 출력하시오!

SQL > select empno, ename,sal,job
          from emp;



문제5. 이름, 월급, 커미션을 출력하시오!

SQL > select ename, sal, comm
          from emp;



문제6. 이름, 월급, 커미션, 월급+커미션을 출력하시오

SQL > select ename, sal, comm, sal+nvl(comm,0)
          from emp;


* 출력시 커미션 값이 null이면 월급+커미션 값이 출력되지 않음

null 값인 경우 
 1) data가 없는 상태 
 2) 알 수 없는 상태 (unknown)


문제7. 월급이 3000인 사원들의 이름과 월급을 출력하시오 !

SQL > select ename,sal
          from emp
          where sal = 3000;

*where 절에 검색 조건을 준다


문제 8. 사원번호가 7788번인 사원의 사원번호, 이름, 월급을 출력하시오

SQL > select empno,ename,sal
          from emp
          where empno = 7788;


문제 9. 사원이름이 SMITH인 사원의 이름과 직업을 출력하시오!

SQL > select ename, job
          from emp
          where ename = 'SMITH';

* 이름은 ' ' 을 사용하여 문자 type이 string 임을 표시 해줌


문제 10. 직업이 SALESMAN인 사원들의 이름과 직업을 출력 하시오

SQL > select ename, job
          from emp
          where job = 'SALESMAN';


문제 11. 월급이 3000 이상인 사원들이 이름과 월급을 출력하시오!

SQL > select ename, sal
          from emp
          where sal >= 3000;

* 연산자의 종류 3가지
1. 산술 연산자 : * , /, +,-
2. 비교 연산자 : >,<,>=,<=,=
                     !=, <>,^= (같이 않거나)
3. 논리 연산자 : and, or, not


문제 12. 직업이 SALESMAN이 아닌 사원들의 이름과 직업을 출력하시오!

SQL > select ename, job
          from emp
          where job != 'SALESMAN';


문제 13. 월급이 1000에서 3000 사이인 사원들의 이름과 월급을 출력하시오!

SQL > select ename, sal
          from emp
          where sal between 1000 and 3000;

* 연산자의 종류 3가지
1. 산술 연산자
2. 비교 연산자
3. 논리 연산자
       - 기타 비교 연산자/  between and


문제 14. 월급이 1000에서 3000 사이가 아닌 사원들의 이름과 월급을 출력하시오

SQL > select ename, sal
          from emp
          where sal not between 1000 and 3000;


문제 15. 사원번호가 7788, 7902 인 사원들의 사원번호와 이름을 출력하시오 !

SQL > select empno, ename
          from emp
          where empno in(7788,7902);

SQL > select empno, ename
          from emp
          where empno = 7788 or empno = 7902;

* 기타 비교 연산자
1. between and
2. in (여러가지 동시에 검색)


문제 16. 직업이 SALESMAN, ANALYST, CLERK이 아닌 사원들의 이름과 직업을 출력하시오!

SQL > select ename, job
          from emp
          where job not in ('SALESMAN', 'ANALYST', 'CLERK');


문제 17. 커미션이 Null인 사원들의 이름과 커미션을 출력하시오!

SQL > select ename, comm
          from emp
          where comm is null;

*기타 비교 연산자
1. between and
2. in
3. is null


문제 18. 커미션이 null이 아닌 사원들의 이름과 커미션을 출력하시오!

SQL > select ename, comm
          from emp
          where comm is not null;


문제 19. 이름의 첫글자가 S(대문자)로 시작하는 사원들의 이름을 출력하시오!

SQL > select ename
          from emp
          where ename like 'S%';

*like 와 같이 쓰이는 것들 (1)
% : wildcard
    이자리에 뭐가 와도, 갯수가 몇개이든 관계없다.


문제 20. 이름의 끝글자가 T로 끝나는 사원들의 이름을 출력하시오!

SQL > select ename
          from emp
          where ename like '%T';


문제 21 이름의 두번째 철자가 M인 사원들의 이름을 출력하시오!

SQL > select ename
          from emp
          where ename like '_M%';

**like 와 같이 쓰이는 것들 (2)
% : 이자리에 뭐가 와도 관계없고 갯수가 몇개든 관계없다.
_ :  이자리에 뭐가 와도 관계 없는 자리 수 1개 이어야 한다.


문제 22. 이름의 세번째 철자가 A인 사원들의 이름을 출력하시오!

SQL > select ename
          from emp
          where ename like '__A%';


문제 23. 이름에 EN 또는 IN을 포함하고 있는 사원들의 이름을 출력하시오!

SQL > select ename
          from emp
          where ename like '%EN%' or ename like '%IN%';


문제 24. 아래의 DATA를 EMP 테이블에 입력하시오

SQL > insert into emp(empno, ename, sal)
          values(1234, 'A%B', 3500);

SQL > select ename, sal
          from emp;


문제 25. 이름의 두번째 철자가 %인 사원의 이름을 출력하시오

SQL > select ename
          from emp
        where ename like '_m%%' escape 'm';

*like 와 같이 쓰이는 것들 (3)
escape



* 생각해봐야할 문제 *

select ename, sal
from emp
where sal between 1000 and 3000;

둘 中 어떤것과 같은가?

1) where sal >= 1000 and sal <=3000; 
2) where sal > 1000 and sal <3000;


답은 1번 

추가로 알게 된 내용 

1. set page 400 / 보이는 페이지를 늘릴 때 사용 (점선이 사라진다.) 

2. ed+Enter키 / 메모장이 열린 후 수정이 가능하다. (닫은 후 -> '/'+Enter키) 




사랑은 어떻게 끝나는가

누군가를 너무 좋아했던 감정 

그 사람 생각밖에 나지 않고, 그저 바라보는 것으로 만족하며, 행복했던 그것 

그 감정은 어떻게 변하고 끝나는가


사랑할 때 이미 끝은 예정되어있다. 

인간의 수명이 정해져 있는 한 모든 시작은 끝을 내포한다. 


그러나 여기서 말하는 끝은 수명과는 관련 없는 끝이다. 

그 사람은 살아있고 나 또한 그와 같지만, 끝이 나버리는 것이다.


사랑이라는 감정이 변하는 것일까

그 감정을 바라고 느끼는 내가 변하는 것일까


그 끝은 나의 의지와는 상관없이 끝이 날 수 있는가

그 끝을 너무 아프지만 염원하면 끝나게 되는가

만약 끝을 바래야 하는 상황이라면 사랑의 감정을 지키지 못함을 부끄러워해야 하는가

그리고 나의 의지로 끝을 외치는 것은, 그러나 그럼에도 불구하고 감정이 남아 있음에 

진정 끝이라고 할 수 있는가 


사람들은 어떻게 누군가 사랑한 감정을 잊어가는가 

그저 무뎌짐을 끝이라 믿으며 살아가는 것일까?

계속 품고 있으면 너무 아프니까...


나의 끝은 언제일까? 무슨 모습을 하고 있을까?

나는 그저 바라보고 있다. 내 모습을 

더는 아프지 않을 때까지... 



정말 좋아했었다. 이 말에 추호의 의심도, 거짓도 없다. 

그녀를 볼 수 있어 행복했고, 그녀와 함께여서 좋았다. 

그녀에게 고백을 하던 그때도 추호의 거짓은 없었다. 

그래서 나에게 하는 것이 그녀가 나를 밀어 내려고 하는 것이었다면 성공적이라 할 것이다. 

눈물이 나올 것 같은 고통 후 찾아 오는 것은 현실이었다. 

부끄러운 벌거숭의 나의 모습이 보였고, 어쩌면 비참해 보이는 나 자신이 보였다.

그래도 후회 하지 않는다. 

그녀로 인해 새로운 세상이 열렸으며, 나를 좀더 바라볼 수 있게 되었다. 

지금의 나의 모습은 씁쓸한 웃음이 될 것이며, 새로운 시작의 기반이 될 것이다. 

그렇게 좋아했던 사람이 이렇게 한 순간에... 될 줄은 몰랐다. 

그러나 정리 할 수는 있을 것 같다. 

만난다면 아마 마지막이 되지 않을까?

이건 비겁한 변명이 아니다. 

나도 스스로에게 비겁한 변명을 하고 있다고 생각하기도 했다. 

그러나 그녀를 좋아했던 것은 근사하고 멋지던 그녀를 웃게 할 수 있을거라 생각해서였다. 

하지만 지금의 나는 그럴 수 없는 것 같다. 

아마도 그래서 일 것이다. 

아직은 차마 행복하라는 말은 못하겠다. 그렇다고 불행하라는 의미도 아니지만, 

쉽게 다른 사람에게 행복하라고 할 만큼 가벼운 마음은 아니었기에, 

거짓이라고 그리 말해버리면 나에게 너무 미안하다. 


마지막이라면 대신 웃으며, 마무리 하고 싶다. 

내가 했던 부담스럽고 투박했던 표현들을 정리하며, 이는 그저 한 서툰 남자의 표현이었음을,

누군가에게 향한 그저 순수한 마음이었음을 전달하고 싶다. 

그녀에게 살면서 기억에 남는 한 사람이었으면 한다. 

나는 이제 정리가 되가고 있다...

이렇게 나는 나를 조용히 덮으며 위로한다. 

그녀가 연락을 받지 않았으면 한다. 

그저 조용히 끝을 보는거다. 

요랸하지 않게 흔들리지 않게, 어렵게 잡은 마음이니 그저 조용히 마무리하고 싶다. 

어쩌면 싫은 표정의 그녀 모습을 보고싶지 않아서 일지도... 아니 그것이 맞는듯 하다.

앞으로 누구를 만나고, 누구를 느끼고, 누구를 사랑할 수 있을지 잘모르겠다.

하지만 항상 내가 누군가를 사랑한다고 표현 할때, 그녀가 잠시 떠오를 듯 싶다.  


Super Bowl Halftime show를 보다가 생각나서 찾아봤는데 

가사가 생각보다 깊은 내용이어서 놀람 

가사 내용 참 좋네~ 





우연히 '우리 결혼했어요'에서 에릭남이 부르는 treasure를 듣고 검색해서 들은 노래 

와 ~ 진짜 잘부른다. 어떻게 이런 목소리에서 이렇게 흥이 나게 부르지? 

겁나 잘부른다... ㅋㅋㅋ

때때로 '고독'을 누리고 싶다는 생각이 엄습한다. 

기존의 즐거웠던 것들이 부질없이 느껴지고, 그 맛을 제대로 느끼지 못한다. 

이런 고통은 주기적으로 찾아오나, 체력적으로 약해졌을 때도 어김없이 찾아온다. 

예전에 즐겼던 것들은 변함이 없는데 내 혀가 마비되어 버린 것 같다. 

그럴 땐 아무도 없고 방해받지 않는 곳으로 가고 싶다.

철저한 고독에 잠기고 싶다. 

고독이란 것은 타의에 의해서 놓여지면 고통이 될 수 있지만 

자의에 의해서 만들어진 고독은 새로움으로 나아가는 힘이 되곤 한다. 

철저하게 나만의 본능과 생각을 마주할 수 있는

누군가의 눈이 아닌 나의 마음에 집중할 수 있는 고독은 어떠한 꿀보다 달콤하다. 

아마도 잃어버린 미각을 살려줄지도 모를 만큼 

그래서 지금 나에게 필요한 것은 철저하게 나에게만 집중할 수 있는 고독이다…


''키워드'로 생각해보기' 카테고리의 다른 글

사랑 감기  (1) 2020.03.01
시간의 상대성  (0) 2019.12.28
온천  (0) 2019.12.24
의문  (0) 2019.12.16
<종이 한 장의 차이>  (0) 2016.04.09

 

- 사진 출처 씨네 21 -

<여인의 향기>

 요즘의 월요일은 나에게는 힘든 시간이다. 영화를 통해서 삶의 의미를 찾고 다시금 나아갈 힘을 얻곤 한다. 웬만한 추천 힐링 무비는 거의 다 보아서 점점 괜찮은 힐링 영화를 찾기 힘들다. 그러다 우연히 '여인의 향기'도 힐링무비라는 것을 알게 되었고 유명한 탱고 장면도 보고 싶어서 다시금 찾아보게 되었다.

 워낙 유명한 작품이고 많은 사람들이 명작이라고 하지만 글쎄... 난 잘 모르겠다. '은하수를 여행하는 히치하이커를 위한 안내서'를 볼 때는 매 장면이 감탄했지만, 여인의 향기에서는 그런 부분이 많지는 않았다. 2시간 가까이 알파치노의 짜증 연기를 보고 있어야 했다. 그래서 알파치노의 연기를 보고 싶은 사람은 2시간이 지루하지 않을지도 모르지만 뭔가 의미를 느끼고 싶은 사람은 1시간 50분부터 보기를 추천한다.

 그래도 1시간 50분부터는 괜찮은 대사들이 나오는데 첫 번째는 '실수를 해서 스텝이 엉키면 그게 바로 탱고라오' 이는 탱고를 인생에 비유 하면서 하는 이야기이다. 우리의 인생은 완벽하지 못하다. 큰 성공을 한 사람들도 인생을 가까이에서 자세히 들여다보면 수많은 실수가 있었고 때로는 그런 실수들이 전화위복이 될때도 있다. 스티브 잡스도 말하지 않았는가 '현재 내가 하고 있는 것은 시간이 지나고 뒤돌아 봤을 때 그 의미를 알 수 있다.' 인생의 실수도 인생이다.

 또 다른 대사는 마지막 부분의 주인공이 '찰리'(크리스 오도넬)를 변호하는 장면에서 찾을 수 있다. '지금까지 나는 나의 인생에서 갈림길들을 직면하였습니다. 나는 어떤 것이 올바른 길인지 항상 알고 있었습니다. 예외 없이 올바른 길을 알고 있었지만 나는 결코 그 길을 택하지 않았습니다. 당신은 왜 그런지 아십니까? 그 길은 너무나 더럽게 어려웠습니다.' 그렇다. 우리는 대부분 올바른 길을 알고 있다. 그러나 그렇게 살다 보면 힘들다는 이유로 또는 두려움으로 올바른 길을 포기한다. 자신이 포기한 길을 '이상'이라고 말하고 다른 이들도 가지 못하는 길이라고 이야기하며 실현될 수 없다고 믿어 버린다.

맞다. 우리가 인정하는 올바른 길이 명료한 만큼 그 길을 걷는 더욱 힘들다. 그런데 올바른 길을 가는 사람들은 그 길이 힘들다는 것을 대부분 알고 간다. 그들은 어려움을 모르는 것도 두려움이 없는 것도 아니다. 다만 그들은 그 어려움도 올바른 길에 하나임을 알고 나아갈 뿐이다. 그들은 두려움이 없고 이상을 꿈꾸는 자들이 아니라, 강한 사람들이다.

여인의 향기는 나에게는 그리 큰 감흥은 되지 못했다. 그러나 주인공 알파치노의 연기는 좋았고, 같이 춤을 춘 여배우는 예뻤으며, 명대사는 있었다.

''리뷰'' 카테고리의 다른 글

<이웃집에 신이 산다>  (0) 2016.03.15
<은하수를 여행하는 히치하이커를 위한 안내서>  (0) 2014.10.26

살다 보면 어떤 선택에서 확신이 잘 서지 않을 때가 있다.
특히 경쟁이나 누군가의 경쟁에서 불안감은 선택의 순간 자충수를 두게 만들 수도 있다.

가령 이성을 만나는 소개팅 자리에서 평소의 자신의 모습이 아닌 남들의 충고나 확신 없는 정보들을 따르다 엉망이 될 때가 있다. 물론 가끔은 그게 먹힐 수도 있지만, 그건 정말 극소수의 운빨이며 또는 그냥 가장 기본적으로 잘생겼기 때문일 확률이 크다. ㅜ ㅜ

이 밖에도 회사에 입사 해서도 시작부터 앞어야 된다는 생각에 튀고 싶어서 했던 행동들이 오히려 부메랑이 되어 자신을 아프게 할 수도 있다.

'확신이 서지 않으면 기본으로 돌아가라'
우리는 흔히 냉철한 승부사로 알고 있는 프로바둑 기사, 프로갬블러 들도 확신이 없다면 승부를 걸지 알고 기다리며 실리를 취하고 때를 기다린다.

기다리다 보면 반드시 기회는 온다. 냉정하게 생각하며, 기본을 착실히 쌓아라!

마지막으로 영화 '타짜' 중에 고니의 대사가 생각난다.
"확신이 없으면 승부를 걸지 마라 ! 안 배웠어 ! " 

 

''나'의 이야기' 카테고리의 다른 글

글을 쓴다  (1) 2019.12.15
< 나는 용기 있는 사람이다. >  (0) 2016.04.09
스스로를 믿자  (0) 2014.10.29
뭐가 '잘 될 거야!'냐..  (0) 2014.10.26
기계상자  (0) 2014.10.26

+ Recent posts