'Database'에 해당되는 글 7건

  1. 2010.01.07 SQL 쿼리 프로파일링
  2. 2009.02.26 서브(Sub) 쿼리 (4)
  3. 2009.02.23 조인(Join) 쿼리
  4. 2009.02.17 MySQL - Commmands out of sync
  5. 2008.04.19 memcached
  6. 2008.01.04 MySQL rename error (errno 121)
  7. 2006.12.13 SQL command
심심 풀이로 쿼리를 '발'로 짜다 보니 이중 삼중의 조인쿼리와 서브쿼리가 한데 어우러진 아주 복잡 미묘한 쿼리를 만들게 되었습니다.

암튼 중요한 것은 바롤 짠 쿼리가 아니라 이 쿼리가 과연 정상적인 성능을 낼 수 있을까 하는 의문이 들더군요.

MySQL을 대상으로 만들긴 했지만, MySQL에서 사실 쿼리가 어떤 순서로 실행 되는지도 모르고(쿼리 계획 이라고 하는 것 같던데..) 내부 구조에도 아는 바가 없어 고민하며 프로파일링 툴을 찾다가 몇 가지 재미있는 링크들을 찾아 간만에 포스팅을 하나 올립니다.


일단 explain 이라는 쿼리 플랜을 보여주는 명령어가 있더군요. SQL 표준이 아닌지라, MySQL에서는 select 절만 지원한다고 하는데, 오라클이나 좀 빵빵한 DB들은 explain update, delete까지 지원하지 않을까 싶습니다.

 

쿼리 플랜이란 쿼리가 실행 되는 순서 정도라고 생각하시면 될 듯합니다.

 

해당 정보를 보시면 특정 테이블에 몇 번 접근 했는지, index를 이용했는지 그냥 쌩으로 리스트를 쭉 훑었는지 등등 튜팅에 도움이 될만한 정보를 많이 보여주더군요.

 * MySQL - Explain 정보보는법
(, MySQL에서는 select 밖에 지원이 안됩니다..ㅠㅠ)

 

그리고 MySQL 5.0 버전 부터는 프로파일러가 붙어서 따라 나오더군요. 사용법은 http://niflheim.tistory.com/56 에 보시면 한글로 아주 친철하게 설명이 되어 있습니다만…쿼리 브라우져로 붙어서 하면 안 나오더군요, 꼭 콘솔로 하셔야만 합니다.

쿼리의 성능
, 실제 쿼리가 실행 되는데 걸리는 시간, 테이블 접근에 걸리는 시간 등의 시간정보들을 얻을 수 있습니다.

 

Posted by kukuta

댓글을 달아 주세요

서브쿼리란?
하나의 테이블에서 검색한 결과를 다른 테이블에 전달하여 새로운 결과를 검색하는 것입니다. 예를 들어 A라는 테이블에서 검색해 나온 결과만을 대상으로 다시 한번 더 쿼리를 날린다는 것입니다. 참고로 하나 이상의 테이블을 연결하여 검색하는 기능은 조인(Join) 쿼리라고 합니다.

기본 문법

SELECT coulmn_name FROM table_name WHERE column_name = (
    SELECT column_name FROM table_name WHERE column_name = some_value
);

생각 보다 간단하지 않나요? 기본적인 것은 일반 쿼리와 동일 합니다. 다만, where 에 조건으로 오는 것이 일반 컬럼이 아니라 또 다른 쿼리라는 것이 차이점 입니다. 실행 순서는 괄호 안에 있는 쿼리를 먼저 실행 하고 해당 쿼리에서 나오는 결과를 이용해 괄호 바깥쪽의 쿼리를 실행 합니다. 물론, 서브 쿼리 안에 또 다른 서브 쿼리를 얼마든지 중첩해서 쓸 수 있습니다. 다만 쿼리가 좀 복잡 해지겠지요

예를 들어 볼까요?
professor라는 테이블이 있다고 생각 해 봅시다. 이 테이블에는 교수의 지위(정교수, 부교수, 시간강사, 전임강사 등등..)와 각 교수들의 이름이 들어 있습니다. 이 테이블을 대상으로 'kukuta'라는 사람의 지위와 같은 위치에 있는 사람들을 검색하고 싶다..라고 상황을 만들어 봅시다. 만일 서브 쿼리가 없다면 아래와 같이 쿼리를 두 번 작성 하겠지요 :

SQL> SELECT position  FROM professor  WHERE name = 'kukuta';

POSITION
--------------------
전임강사

SQL> SELECT name  FROM professor  WHERE position = '전임강사';

NAME
----------
kukuta
염일웅
전은지
백미선

사람이 직접 한다면야 눈으로 보고 첫 번째 쿼리의 결과를 기억했다가 두 번째 쿼리를 만들면 됩니다만...프로그램(C/C++ API 같은..)을 이용 한다면 첫번째 결과를 어딘가에 저장했다가 두 번째 쿼리를 만들 때 넣어 줘야만 합니다. 마냥 불편 하지요.
하지만 서브 쿼리가 있다면 다음 처럼 한번의 쿼리로 모든 것을 해결 할 수 있습니다 :

 SQL> SELECT name  FROM professor  WHERE position = (
                 SELECT position  FROM professor WHERE name = 'kukuta'
          );

NAME
----------
kukuta
염일웅
전은지
백미선

보다 더 간단해 지지요? 프로그램을 짤 때는 이것만큼 고마운게 없답니다.

'진리는어디에' 카테고리의 다른 글

C++ #line은 뭐지?  (0) 2010.02.02
WideCharToMultiByte()  (0) 2009.03.20
서브(Sub) 쿼리  (4) 2009.02.26
조인(Join) 쿼리  (0) 2009.02.23
fcntl() 함수를 이용한 File locking  (0) 2009.02.22
MySQL - Commmands out of sync  (0) 2009.02.17
Posted by kukuta
TAG Database, SQL

댓글을 달아 주세요

  1. 추종자 2009.02.26 10:32  댓글주소  수정/삭제  댓글쓰기

    SELECT a.name
    FROM professor a, professor b
    WHERE a.position = b.position
    and b.name = 'kukuta'
    ..................................
    간혹 서브쿼리 가 안먹는 DB가 있었던듯...

  2. Favicon of http://rhea.pe.kr BlogIcon Rhea君 2009.03.12 00:30  댓글주소  수정/삭제  댓글쓰기

    Delete * FROM USER WHERE id = 'kukuta'

    이것만 있으면 됩니다... .

  3. sjhong 2013.05.23 17:11  댓글주소  수정/삭제  댓글쓰기

    명료한 설명 감사합니다.

조인(Join)의 개념
여러개의 테이블을 결합하여 데이터를 검색 하는 것입니다. 예를 들어 A와 B라는 테이블을 따로 select하는 것이 아니라 동시에 select를 한다고 생각하시면 됩니다. 그 결과 중 특정 컬럼들의 값을 비교해서 같은 것들(혹은 다른 것들)만 select한다던지 하는 것을 조인이라고 합니다. where 절로 구분 하는 방법에 따라 여러가지 이름으로 불리고 있지만 간단한 개념이 이렇다는 것입니다.

조인(Join)의 종류
EQUI JOIN, NON-EQUI JOIN, OUTER JOIN, SELF JOIN 등 여러가지 조인이 있지만, 여기서는 Equi Join에 대해서만 다루도록 하겠습니다(제가 DB쪽 일을 하는게 아니라서 그런지 다른 Join은 잘 안쓰더군요..-0-)

EQUI JOIN
조인 대상 테이블에서 공통 칼럼을 '=' 비교를 통해, 같은 값을 가지는 행을 연결하여 결과를 생성하는 조인 방법 입니다. 

예를 들기 이전에 설명의 편의를 위해 EQUI JOIN에서 테이블 간의 연결 고리가 되는 공통 칼럼을 Join Attribute라고 정의 하겠습니다. 이 Join Attribute는 참조 무결성을 가져야 하며 한쪽 컬럼의 값이 NULL일경우 조인 결과에서 제외 됩니다.

SELECT table1.column, table2.column FROM table1, table2 WHERE table1.column1 = table2.column2;

주목 할것은 : 

  • column 이름 앞에 테이블 이름으로 컬럼의 스코프를 지정 줘 스코프를 구분 했다는 것.
  • FROM 절에서 테이블이 하나가 아니라 두 개(사실 N개도 가능)를 썼다는 것.
  • WHERE에서 서로 다른 두 테이블의 컬럼을 비교 하고 있다는 것.

정도 입니다.

참고로 말씀드리면, 꼭 다른 테이블에 있는 컬럼끼리 조인 쿼리의 대상이 될 필요는 없다는 것입니다. 동일한 테이블의 컬럼들 내에서도 조인은 가능 합니다. 보통 이런 것을 Self join이라고도 하더군요.

'진리는어디에' 카테고리의 다른 글

WideCharToMultiByte()  (0) 2009.03.20
서브(Sub) 쿼리  (4) 2009.02.26
조인(Join) 쿼리  (0) 2009.02.23
fcntl() 함수를 이용한 File locking  (0) 2009.02.22
MySQL - Commmands out of sync  (0) 2009.02.17
구조체 비트 단위 멤버  (1) 2009.02.14
Posted by kukuta
TAG Database, SQL

댓글을 달아 주세요

MySQL을 사용하던 서버가 Commands out of sync 라는 에러를 내며서 정상적으로 동작하지 않는다. 무슨 일인가 싶어 구글에게 물어 봤다. 그러니 나오는 대답..
If you get Commands out of sync; you can't run this command now in your client code, you are calling client functions in the wrong order.

This can happen, for example, if you are using mysql_use_result() and try to execute a new query before you have called mysql_free_result(). It can also happen if you try to execute two queries that return data without calling mysql_use_result() or mysql_store_result() in between.

만일 Command out of sync; you can't run this command now 라는 메시지를 클라이언트 코드에서 보게 된다면, 클라이언트 함수의 순서를 잘 못 호출하고 있는 것이다!!

예를 들자면, mysql_use_result() 함수를 호출하고 mysql_free_result() 호출 하기 이전에 새로운 쿼리를 실행 하면 이런 현상이 발생한다. 또 다른 경우로 리턴 데이터가 있는 두 개의 쿼리를 mysql_use_result()이나 mysql_store_result() 없이 연속으로 호출 하면 같은 현상이 발생한다.

해석이 제대로 된건지는 잘 모르겠다만...들어 보니 thread safe가 제대로 맞지 않아서 이렇게 되었다고 한 것 같은데...

언제 코드를 또 다 살펴 보나...-_-;;;
Posted by kukuta

댓글을 달아 주세요

memcached

도구의발견 2008.04.19 23:14

'memcached' 가 무엇인가?
memcached라고하는 고성능(물론 자신들이 말하는 것입니다)의 분산 메모리 캐싱 데몬입니다. 주로 웹환경에서 사용되기 위해 디자인 되었고, memcached를 사용하여 DB에 직접적으로 가해지는 부하를 상당히 줄일 수 있다고 합니다.

데몬 시작
일단 memcached 데몬을 실행 합니다. 설정파일 따우는 없으면 몇개의 커맨드라인을 통해 셋팅이 이루어 집니다 :

# ./memcached -d -m 2048 -l 10.0.0.40 -p 11211
  • -d : memcached를 데몬 형태로 띄우도록 지정합니다.
  • -m : memcached는 사용할 메모리 크기를 지정합니다.
    위의 예제에서는 2GB를 사용하도록 설정 되어 있습니다.
  • -l : listen 아이피를 지정합니다.
  • -p : listen port를 지정합니다.

download : http://www.danga.com/memcached/download.bml

'도구의발견' 카테고리의 다른 글

개발자를 위한 .vimrc 설정  (0) 2008.07.15
SVN 사용하기  (0) 2008.04.30
memcached  (0) 2008.04.19
msxml 파서 사용하기  (2) 2008.04.03
Dependency Walker 2.2  (0) 2008.03.21
Shell 프롬프트에서의 단축키  (0) 2008.03.11
Posted by kukuta

댓글을 달아 주세요

DB A에 있는 테이블들을 DB B로, rename을 사용하여 옮기는 코드가 오류를 내고 있다는 연락을 받았다. 다른 모든 테이블들은 아무런 군소리 없이 옮겨 지는데 딱 한 테이블만 121 에러 코드를 내면서 옮겨 지지 않았다.

무슨 소린가 해서 구글 박사님게 물어 보니 외부 참조 키가 중복이 되면 121 에러 코드가 리턴 된단다. 그래서 테이블 스키마를 살펴 보니...아무런 constraint가 없었다. 이 테이블은 그냥 컬럼들의 나열일 뿐이었다.

/**
1) MySQL rename menual page : http://dev.mysql.com/doc/refman/4.1/en/rename-table.html
2) 121 error : http://forums.mysql.com/read.php?22,33999,76181#msg-76181

1)은 rename을 하기 위해서는 lock이 걸려 있지 않아야 한다는 것을 길게 이야기 하고 있고, 2)는 외부키 참조 중복과 더 불어, DB파일 자체가 잘 못 될 수도 있음을 이야기 한다.
*/

한창 이 문서 저 문서를 뒤지고 살펴 보던 중 /usr/local/var 밑에 MySQL의 에러 로그가 남는다는 사실을 알았다.(뭐...설정마다 다를 수 있지만..)

그래서 로그를 살펴 보니..이 일이 이번에 발생한 것이 아니고 아주 오래전...2005년 12월 부터 발생하고 있었던 사실을 알아 냈다.

결론은 환경이나 코드상의 버그가 아니라, MySQL자체의 버그이거나, 파일이 깨진 것으로 판단. table을 drop하고 재생성했다. 결과는 당연히 정상 동작하고 있다. 하지만 이거 하나 하려고, 고생했던 수 많은 시간들을 생각하면 눈물이 난다..ㅠㅠ

---------------------------------------------------------------------------------------------------

위의 내용은 사실이 아니었습니다. 속지 마시기를...-_-;;
제가 올린 글을 제가 속지 말라고 하다니 웃기긴 하군요..아무래도 이 문제는 DB의 타입에 문제가 있었던듯 합니다.

InnoDB에서 ISAM으로 변경을 하니 에러가 나지 않는군요.

이게 정확한 해결 방법인지는 저도 잘 모르겠습니다만..아뭏튼 이렇게 하고 난 후에는 에러가 발생하지 않고 있습니다. 혹시 정확한 원인을 아시는 분은 가르쳐 주시면 감사하겠습니다.(-_-)(_ _)

Posted by kukuta

댓글을 달아 주세요

SQL command

진리는어디에 2006.12.13 13:27

CREATE DATABASE <Database Name>

새로운 데이터베이스를 생성

CREATE TABLE <Table Name>( schema.. )

새로운 테이블을 생성
ex) CREATE TABLE tab (val INT);

INSERT INTO <Table Name> [(field Name, ... )] VALUES (data, ...)

CREATE문으로 생성된 테이블에 데이터를 저장

UPDATE <Table Name> SET <field Name>=<New Data> WHERE expr

UPDATE 문은 INSERT 문으로 저장되어 있는 데이터 수정

DELETE FROM <Table Name> WHERE expr

테이블에 있는 데이터를 삭제 할때 사용하는 쿼리문
테이블 자체를 삭제하는 DROP과 구분 되어야 한다.

ALTER TABLE <Table Name> ADD <Field Name>

테이블에 새로운 필드 추가
ex) ALTER TABLE tableName ADD newFieldName varchar(30);

ALTER TABLE <Table Name> DROP <Field Name>

테이블에 기존의 필드 삭제

ALTER TABLE <Table Name> MODIFY <Field Name>

테이블의 기존의 필드 수정
ex) ALTER TABLE tableName MODIFY exsistFieldName varchar(25) not null;

'진리는어디에' 카테고리의 다른 글

const vs mutable  (4) 2006.12.21
PHP - 문자열 취급하기  (0) 2006.12.14
가변인자를 이용한 함수(va_list)  (10) 2006.12.13
SQL command  (0) 2006.12.13
Writing a Windows Service Program  (8) 2006.12.11
Python 정규 표현식  (1) 2006.12.11
Posted by kukuta
TAG Database, SQL

댓글을 달아 주세요