DB Index 가비지 파일 정리 명령어

vacuum verbose analyze;

 

 

베큠 관련 정리글을 남겨둔다.

https://blog.gaerae.com/2015/09/postgresql-vacuum-fsm.html

 

번외 :

 

현재 트랜잭션 실형중인 쿼리 조회 

select * from pg_stat_activity order by query_start asc; 

 

실행중인 쿼리 취소하기 

select pg_cancel_backend(pid int);

> pid int 값은 pg_stat_activity 쿼리조회 결과에서 실행중인 쿼리를 취소할 pid 컬럼의 int값을 pg_cancel_backend 함수 실행하면

쿼리가 취소된다. 

 

- Index Range Scan

> B*Tree 인덱스의 가장 일반적이고 정상적인 형태의 액세스 방식, 

인덱스 루트에서 리프 블록까지 수직적으로 탐색한 후에 '필요한 범위만' 스캔한다.

 

* 인덱스를 Range Scan 하려면 선두 컬럼을 가공하지 않은 상태로 조건절에 사용해야 한다. 반대로 말하면, 선두 컬럼을 가공하지 않은 상태로 조건절에 사용하면 Index Range Scan은 무조건 가능하다. 

 

- Index Full Scan

> 수직적 탐색없이 인덱스 리프 블록을 처음부터 끝까지 수평적으로 탐색하는 방식

대게 데이터 검색을 위한 최적의 인덱스가 없을 때 차선으로 선택

 

- Index Unique Scan

> 수직적 탐색만으로 데이터를 찾는 스캔 방식으로서, Unique 인덱스를 '=' 조건으로 탐색하는 경우에 작동

Unique 인덱스가 존재하는 컬럼은 중복 값이 입력되지 않게 DBMS가 데이터 정합성을 관리 해 준다.

 

- Index Skip Scan

인덱스 선두 컬럼을 조건절에 사용하지 않으면 옵티마이저는 기본적으로 Table Full Scan을 선택한다. Table Full Scan 보다 I/O를 줄일 수 있거나 정렬된 결과를 쉽게 얻을 수 있다면, Index Full Scan을 사용하기도 함.

> 조건절에 빠진 인덱스 선두 컬럼의 distinct Value 개수가 적고 후행 컬럼의 distinct Value 개수가 많을 때 유용하다. 

 Index Skip Scan 은 루트 또는 브랜치 블록에서 읽은 컬럼 값 정보를 이용해 조건절에 부합하는 레코드를 포함할 '가능성이 있는' 리프 블록만 골라서 액세스 하는 스캔 방식.

 

- Index Fast Full Scan

Index Fast Full Scan이 Index Full Scan보다 빠른 이유는, 논리적인 인덱스 트리 구조를 무시하고 인덱스 세그먼트 전체를 Mulitblock I/O 방식으로 스캔하기 때문이다. 

 Index Fast Full Scan은 Mulitblock I/O방식을 사용하므로 디스크로부터 대량의 인덱스 볼록을 읽어야 할 때 큰효과를 발휘한다. 속도는 빠르지만, 인덱스 리프 노드가 갖는 연결 리스트 구조를 무시한 채 데이터를 읽기 때문에 결과집합이 인덱스 키 순서대로 정렬되지 않는다. 

 Index Range Scan 또는 Index Full Scan과 달리, 인덱스 파티션 돼 있지 않더라도 병렬 쿼리가 가능한 것도 중요한 특징중 하나다.

병렬 쿼리 시에는 Direct Path I/O 방식을 사용하기 때문에 I/O 속도가 더 빨라진다. 

 

- Index Range Scan Descending 

Index Range Scan과 기본적으로 동일한 스캔 방식이다. 인덱스를 뒤에서 부터 앞쪽으로 스캔하기 때문에 내림차순으로 정렬된 정렬된 결과집합을 얻는다는 점만 다르다. 

 

 

 

 

 

https://m.blog.naver.com/anytimedebug/221222479261

 

[PostgreSQL] pg_dump 명령어 및 옵션

※ 해당 내용은 PostgreSQL 9.6의 내용을 기반으로 작성하였습니다.명령어 구성옵션-a --data-only 테...

blog.naver.com

 

 

1.3.5 논리적I/O vs 물리적I/O

논리적 블록 I/O는 sql문을 처리하는 과정에서 메모리 버퍼캐시에서 발생한 총 블록 I/O

물리적 블록 I/O는 디스크에서 발생한 총 블록 I/O

메모리I/O는 전기적 신호인데 반해, 디스크I/O는 액세스 암(arm)을 통해 물리적 작용이 일어나므로 메모리 I/O에 비해 상당히 느림 (보통 10,000)배 느리며, 디스크 경합이 심할 때는 더 느리다.

 

버퍼캐시 히트율 : 버퍼캐시 효율을 측정하는데 전통적으로 가장 많이 사용해 온 지표

BCHR = ( 캐시에서 곧바로 찾은 블록수 / 총 읽은 블록 수 ) x 100

           = ( ( 논리적 I/O - 물리적 I/O ) / 논리적 I/O ) x 100

           = ( 1 - ( 물리적 I/O ) / ( 논리적 I/O ) ) x 100

 

tip. BCHR은 읽은 전체 블록 중에서물리적인 디스크I/O를 수반하지 않고 곧바로 메모리에서 찾은 비율을 나타낸다고 볼수있다고한다.

* 실제 SQL 성능을 향상하려면 물리적I/O가 아닌 논리적I/O를 줄여한다는 사실을 알수있음.

 - 논리적 I/O를 줄이는 방법으로는 SQL을 튜닝해서 읽는 총 블록 개수를줄이면 됨. (당연한 이야기...)

 

1.3.6 Single Block I/O vs Multi Block I/O

 메모리 캐시가 클수록 좋지만, 데이터를 모두 캐시에 적재할수는 없다. ( 비용적한계, 기술적한계 때문에..) 그리하여 일부만 캐시에 적재해서 읽을수 있는데.

한번에 한 블록씩 요청해서 메모리에 적재하는 방식이 'Single block I/O' 이며, 한 번에 여러 블록씩 요청해서 메모리에 적재하는 방식을 'Multi block I/O'라고 한다.

 - 인덱스를 이용 할때는 기본적으로 인덱스와 테이블 블록 모두 Single block I/O 방식을 사용한다.

 - 반대로, 많은 데이터 블록을 읽을 때는 Multiblock I/O 방식이 효율적이며, 인덱스를 이용하지않고 테이블 전체 스캔을 할때 사용한다.

 

1.3.7 Table Full Scan vs Index Range Scan

테이블 전체를 스캔해서 읽는방식, 인덱스를 이용해서 읽는 방식 2가지로 테이블에 저장된 데이터를 읽는방식이 존재한다.

( 많은 개발자의 인식과 달리 인덱스가 sql 성능을 떨어뜨리는 경우도 상당히 많다는 점도 알아야한다고 함 ex.집계용 sql과 배치 프로그램)

 

1.3.8 캐시 탐색 메커니즘

Direct Path I/O를 제외한 모든 블록 I/O는 메모리 버퍼캐시를 경유한다. 아래 오퍼레이션은 모두 버퍼캐시 탐색과정을 거친다.

- 인덱스 루트 블록 읽을때

- 인덱스 루트 블록에서 얻은 주소 정보로 브랜치 블록을 읽을 때

- 인덱스 브랜치 블록에서 얻은 주소 정보로 리프 블록을 읽을때

- 인덱스 리프 블록에서 얻은 주소 정보로 테이블 블록을 읽을때

- 테이블 블록을 Full Scan 할때

 

공유캐시의 특정 자원을 두 개 이상 프로세스가 같이 사용할수없다, 같이 사용하는것 처럼 보이지만, 특정 순간에는 한 프로세스만 사용 할수있다. 그 순간 다른 프로세스는 줄 서서 기다려야 한다. 이런 줄서기가 가능하도록 지원하는 메커니즘이 래치(Latch)다.

위 설명을 이해하기 위해 서적에서는 카쉐어링 서비스로 예를 들었다( ex. 쏘카, 그린카) 

 

추가개념_

버퍼 Lock :  버퍼블록의 자체에 대한 직렬화 문제를 해결

1.2 SQL 공유 및 재사용

1.2.1 소프트파싱VS하드파싱

라이브러리 캐시(Library Cache) :

sql파싱, 최적화, 로우소스생성 과정을 거쳐 생성한 내부 프로시저를 반복 재사용할수있도록 캐싱해두는 메모리공간

- SGA(System Global Area) 서버프로세스와 백그라운드 프로세스가 공통으로 액세스하는 데이터와 제어구조를 캐싱하는 메모리공간

 

소프트파싱(Soft Parsing) : SQL을 캐시에서 찾아 곧바로 실행단계로 넘어감

하드파싱(Hard Parsing) : SQL을 캐시에서 찾는데 실패하여 최적화 및 로우소스 생성단계까지 모두 거치는것

 

옵티마이저가 SQL을 최적화할때 사용하는 정보 종류

- 테이블, 컬럼,  인덱스 구조에 관한 기본 정보

- 오브젝트 통계 :  테이블 통계, 인덱스 통계, (히스토그램을 포함한)칼럼 통계

- 시스템 통계 :  CPU속도,  Single Block I/O 속도, Multiblock I/O 속도 등

- 옵티마이저 관련 파라미터

 

1.2.2 바인드 변수의 중요성

이름없는 SQL문제

sql 자체가 이름이기 때문에 텍스트 중 작은 부분이라도 수정되면 그 순간 다른 객체가 새로 탄생하는구조

일회성 또는 무효화된 sql까지 모두 저장하려면 많은공간이 필요하고, 그만큼 sql을 찾는속도가 느려진다(sql영구저장안하는이유)

*sql텍스트가 변하면 sql id도 변한다

 

공유가능 SQL

동일한 sql 쿼리를 반복하게되면 내부 처리 루틴은 모두 같을것이다.

그렇다면, sql쿼리 조건문에 해당되는 파라미터를 처리하는 프로시저 하나를 공유하면서 재사용하는것이 유리할것

파라미터 Driven 방식으로 sql을 작성하는 방법이 제공되는데 이것이 바로 바인드 변수다.

 

1.3 데이터 저장 구조 및 I/O 메커니즘

1.3.1 I/O = SLEEP (os또는 I/O서브시스템이 I/O를 처리하는 동안 프로세스는 잠을 자기 때문에..)

 

1.3.2 데이터베이스 저장 구조

데이터를 저장하라면 *테이블스페이스를 생성해야한다. (테이블스페이스 : 세그먼트를 담는 컨테이너로서, 여러개의 데이터 파일로 구성)

테이블 스페이스를 생성했으면, *세그먼트를 생성한다. 세그먼트는 테이블, 인덱스처럼 데이터 저장공간이 필요한 오브젝트이다.

(테이블, 인덱스를 생성할때 데이터를 어떤 테이블스페이스에 저장할지를 지정한다.)

세그먼트는 여러 *익스텐트로 구성됨, 파티션 구조가 아니라면 테이블도 하나의 세그먼트, 인덱스도 하나의 세그먼트가 된다. LOB컬럼은 그 자체가 하나의 세그먼트를 구성하므로 자신이 속한 테이블과 다른 별도 공간에 값을 저장한다. (익스텐트는 공간을 확장하는 단위) 

 테이블이나 인덱스에 데이터를 입력하다가 공간이 부족해지면 해당 오브젝트가 속한 테이블스페이스로부터 익스텐트를 추가로 할당받음

 익스텐트는 역속된 블록들의 집합이기도 한다. 익스텐트 단위로 공간을 확장하지만,  사용자가 입력한 레코드를 실제로 저장하는 공간은 데이터 블록이다. ( != DB2, SQL서버 같은 DBMS는 페이지page 라는 용어사용)

 즉,  한 블록에 저장된 레코드는 모두 같은 테이블 레코드이다 :) 다중 테이블 클러스터일 때는 한 블록에 여러 테이블 레코드가 같이 저장

 

데이터베이스 저장 구조 용어정리 -

블록 :  데이터를 읽고 쓰는 단위

익스텐트 : 공간을 확장하는 단위, 연속된 블록 집합

세그먼트 : 데이터 저장공간이 필요한 오브젝트(테이블, 인덱스, 파티션, LOB등)

테이블스페이스 : 세그먼트를 담는 컨테이너

데이터파일 : 디스크 상의 물리적인 OS파일

 

+ DBA(Data Block Address)

: 모든 데이터 블록은 디스크 상에서 몇 번 데이터파일의 몇 번째 블록인지를 나타내는 자신의 고유 주소값을 가짐.

 

1.3.3 블록 단위 I/O

오라클은 기본적으로 8KB 크기의 블록을 사용하므로 1Byte를 읽기 위해서 8KB를 읽는 셈

(오라클은 2KB, 4KB 16KB 크기 블록을 사용할 수도 있다. MS SQL은 8KB 단일 사이즈 블록만 지원)

 

1.3.4 시퀀셜 액세스 VS 랜덤 액세스

테이블 또는 인덱스 블록을 읽는 방식으로는 2가지 방식이 있다

시퀀셜(Sequential) 액세스 : 논리적 또는 물리적으로 연결된 순서에 따라 차례대로 블록을 읽는 방식

오라클은 세그먼트에 할당된 익스텐트 목록을 세그먼트 헤더에 맵으로 관리하여 테이블 블록간의 서로 논리적인 연결고리를 시퀀셜 방식

으로 액세스하게 한다.

 

- 읽어야 할 익스텐트 목록을 익스텐트 맵에서 얻고, 각 익스텐트의 첫 번째 블록 뒤에 연속해서 저장된 블록을 순서대로 읽는것이 FullTableScan 이다. 

 

랜덤(Random) 액세스 :  논리적, 물리적인 순서를 따르지 않고, 레코드 하나를 읽기 위해 한 블록씩 접근하는 방식

SQL 처리 과정과 I/O

1.1 SQL 파싱과 최적화

1.1.1 SQL(Structured Query Language)은 구조적(structured)이고 집합적(set-based)이고

선언적(declarative)인 질의 언어

 

1.1.2 SQL최적화 :

DBMS 내부에서 프로시저를 작성하고 컴파일하여 실행 가능한 상태로 만드는 전 과정

#sql최적화 과정

1. sql파싱 (파싱트리생성, Syntax체크, Semantic체크)

2. SQL최적화

3. 로우 소스 생성

 

1.1.3 SQL옵티마이저( LIKE 자동차 네비게이션 ):

사용자가 원하는 작업을 가장 효율적으로 수행할수있는 최적의 데이터 액세스 경로를 선택해주는 DBMS의 핵심 엔진

 

1.1.4 sql실행계획의 비용(cost)는 어디까지나 예상치

 

1.1.5 옵티마이저 힌트: 

개발자가 직접 더 효율적인 액세스 경로를 찾아낼수도 있음, 이럴 때 옵티마이저 힌트를 이용해 액세스 경로를 바꿀수 있음

* 옵티마이저 힌트 주의사항:

힌트안 인자 나열할땐 콤마사용 가능하나, 힌트와 힌트사이에는 사용하면 안됨, 테이블 지정할 때 스키마 명까지 명시하면 안됨, from절 테이블명에 alias를 지정햇다면, 힌트에도 반드시 alias를 사용해야 한다.(alias 사용 안할시 그 힌트는 무시됨)

(옵티마이저 힌트 사용방법: 주석 기호에 '+'를 붙이면 됨)

 

 

 

 feat. 친절한SQL튜닝  

 

BufferedReader, StringTokenizer 는 문자열로 활용하기 위하여 사용. BufferedReader를 사용하는 것이 Scanner를 사용하는 것보다 빠르다.
BufferedReader는 문자열에 최적화 되어 있음.

BufferedReader
readLine() 입력값으로 들어온 데이터를 한줄로 읽어서 String으로 바꾸는 메소드 /단, 무조건 한줄만 읽는다

close() 입력작없이 끝나면 close 로 입력스트림을 닫고 사용하던 자원을 해제
+ 추가적으로 BufferedReader를 사용하려면 예외처리를 해주어야한다 IOException throws처리 

BufferedWriter
write() 출력할 내용 담기
flush() 버퍼를 비워내는 동시에 콘솔에 출력 /write()만 사용한다고 콘솔에 출력되는게 아니라, 반드시 flush를 써줘야햐 한다
close() 출력이 끝나면  close로 스트림을 닫음

StringTokenizer
BufferedReader는 잘라서 배열과 같이 인덱스를 사용하여 접근하여 사용.
StringTokenizer는 공백이 있다면 뒤에 문자열이 공백 자리를 땡겨 채우도록 한다.
StringTokenizer가 BufferedReader보다 빠르게 사용될 수 있다.
문자열을 자르게 위해 split을 사용할땐, split은 정규식을 기반으로 자르는 로직으로서 내부는 복잡하다. 그에 비해 StringTokenizer의 nextToken()메소드는 단순히 공백 자리를 땡겨 채우는 것이다. 그렇기 때문에 속도 차이가 날 수 밖에 없다.
정규식이나 인덱스 접근과 같은 처리가 필요없다면 StringTokenizer를 사용하는 것이 효율적이

'Back Dev > JAVA' 카테고리의 다른 글

Static (정적변수와 메소드)  (0) 2021.08.06
JAVA환경에서 CMD 명령어 실행  (0) 2020.11.05
날짜비교  (0) 2020.03.31
JAVA 문자열비교  (0) 2019.07.26
파일확장자 추출(부제: 문자열자르기)  (0) 2019.07.04

static 변수

1. 항상 값이 변하지 않는 경우 메모리 이점이 있음

 > 변수에 Static을 선언하면 JAVA는 메모리 할당을 한번만 할당하여 메모리 사용에 이점이있음

 

* 선언한 변수의 값이 변경되지 않길 원한다면 static 앞에 final을 선언하면 됨

  > final 선언시 선언한 값을 변경하지 못하게됨, final 선언된 값을 변경 할 경우 예외발생

 

2. 공유의 개념 (변수값 공유) 

   대부분 변수값을 공유하고자 static을 이용

 

static 메소드

 static 메소드 안에서는 인스턴스 변수 접근이 불가능

단, static변수일 경우 static메소드에서 접근이 가능

 

[응용] Singleton pattern (싱글톤 패턴)

단 하나의 객체만을 생성하게 강제하는 패턴 

 

'Back Dev > JAVA' 카테고리의 다른 글

BufferedReader, StringTokenizer 정리  (0) 2021.12.01
JAVA환경에서 CMD 명령어 실행  (0) 2020.11.05
날짜비교  (0) 2020.03.31
JAVA 문자열비교  (0) 2019.07.26
파일확장자 추출(부제: 문자열자르기)  (0) 2019.07.04

props 와 state 차이 

props readOnly (수정불가)

state modify, (setState를 이용해서 수정)

 

// props와 state는 render함수 호출

 

상위컴포넌트가 하위 컴포넌트를 명령할때는 props를 이용해서 컨트롤

하위컴포넌트가 상위 컴포넌트를 이벤트를 통해서 컨트롤

 

 

 

react 학습전 선행학습주제 -

javaScript 클래스, 화살함수, const & let [immutability(변경불가성)]

 

+ 보충개념 redux 

try {
			InputStream is;
			is = Runtime.getRuntime().exec( 파일경로 ).getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is, "MS949"));
			
			result = 1;
			
			br.close();
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

 

'Back Dev > JAVA' 카테고리의 다른 글

BufferedReader, StringTokenizer 정리  (0) 2021.12.01
Static (정적변수와 메소드)  (0) 2021.08.06
날짜비교  (0) 2020.03.31
JAVA 문자열비교  (0) 2019.07.26
파일확장자 추출(부제: 문자열자르기)  (0) 2019.07.04

+ Recent posts