Mysql 인덱스 역순 - Mysql indegseu yeogsun

= index values are always stored in ascending order

= 참고> http://stackoverflow.com/questions/10109108/how-do-i-create-a-desc-index-in-mysql

= 참고> Reserved Key words : http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html

= 개요

예> ORDER BY log_time DESC, msgid LIMIT 256]

위처럼 DESC으로 인덱싱이 필요한데 인덱스 설정시 키워드로는 존재하지만 구현이 안되어 있어서 실제 인덱싱이 안되고

무조건 ASC로만 동작하여 성능이 안나온다는 얘기임.

= 그러나 방법을 찾으면 ......

= reverse 매퍼를 두어서 해결하는 방법을 제시하고 있는 곳이 있음.

= 참고> http://stackoverflow.com/questions/10382346/is-it-possible-to-make-mysql-use-an-index-for-the-order-by-1-desc-2-asc

As a suggestion you would better have a reversed_root column which is Integer.MAX_VALUE - rootAND have an index on (reversed_root, path). Then you can have a query as :

SELECT * FROM Board ORDER by reversed_root ASC,path ASC LIMIT 0,100

TIMESTAMP 최대값 =>
참고> http://dev.mysql.com/doc/refman/5.6/en/datetime.html

DATETIME : '1000-01-01' to '9999-12-31'
TIMESTAMP: '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07'
참고> 타입별 최대값 : http://help.scibit.com/mascon/masconMySQL_Field_Types.html

자동으로 Reverse값 넣는 방법

Google key Word> mysql default value other column

http://stackoverflow.com/questions/15384429/mysql-set-field-default-value-to-other-column

Oracle> REMAINING INT default MAX_VALUE - BOOKED_UNITS,

MySQL>

Mysql 인덱스 역순 - Mysql indegseu yeogsun

TimeStamp> 참고> 날짜 시간 연산 : http://www.nazuni.pe.kr/web/dev/mysql/functions_datetime.php


reverse_time ==> INT(10)<Below Why Syntax Error ??? > => Use Below Command
delimiter //
CREATE TRIGGER MyTrigger_ReverseTimeStamp BEFORE INSERT ON ac_ap_log FOR EACH ROW
BEGIN
 IF NEW.reverse_time IS NULL THEN SET
NEW.reverse_time := UNIX_TIMESTAMP('2038-01-19 03:14:07') - UNIX_TIMESTAMP(CURRENT_TIMESTAMP); END IF;
END;//
CREATE TRIGGER MyTrigger_ReverseTimeStamp BEFORE INSERT ON ac_ap_log FOR EACH ROW
 IF NEW.reverse_time IS NULL THEN SET
NEW.reverse_time := UNIX_TIMESTAMP('2038-01-19 03:14:07') - UNIX_TIMESTAMP(CURRENT_TIMESTAMP); END IF;;//delimiter ;

###### MYSQL에서 올림차순 인덱스를 만들어 보자. #######

우선 MYSQL에서는 올림차순 인덱스를 정의 할 수가 없습니다...

즉, 1,2,3,4,5,6... 식의 내림차순 인덱스는 정의 할 수가 있지만....

오라클의 힌트 등을 이용한 올림차순 인덱스는 정의 할 수가 없지요...

올림차순 인덱스는 중요합니다...

엉.. 머리가 딸려서.. 예를 들어 설명하겠습니다...

활용하시길..

게시판에서 등록일을 타임스템프값을 이용했을 경우를 예로 들어보겠습니다...

타임스템프값은 시간이 지날수록 증가합니다....

물론 1970년대 부터 2037년 언제까지의 한계가 존재하지만.. 말입니다...

따라서 인덱스 컬럼으로 지정한다하여도...

올림차순 형태로 게시물을 가져와야 합니다...(최근에 등록된 글.. 오늘 등록된 글..)

따라서 필수로 order by DESC를 사용해야 합니다...

DESC를 사용하는 순간부터는 인덱스하고는 상관이 없습니다...

만약 10만건의 게시물 중에서 오늘 등록된 글의 정보를 가져오려면...

안봐도 훤한 결과가 나타납니다...

select * from 어쩌구 where 시간 >= 오늘타임스템프 order by 시간 DESC

등과 같이 처리를 해 주어야 겠지요....

내부적으로 인덱스를 사용할 수가 없으니까... 전체 게시물을 스캔해야 할 것입니다...

하지만 꽁수(?)를 이용하여 시간컬럼을 올림차순 인덱스 효과가 있도록 해 봅시다..

뭐 대단한 건 없습니다...

타임스템프값을 최근일수록 작은 값이 되도록 해주면 됩니다...

벌써 이해하신 분이 계시겠지만...

0-타임스템프값을 갖도록 해 주는 거지요...

그럼 최근입력순으로 정렬이 가능하겠지요...

MYSQL에서는 내림차순이지만... 우리는 올림차순 비슷하게 이용할 수 있다는 겁니다...

물론 값을 가공할때는 절대값으로 하면 되구요...

아까와 같은 예시를 이번엔 인덱스를 사용해 봅시다..

select * from 어쩌구 where 시간 <= 오늘타임스템프 order by 시간

어떻습니까.. DESC가 필요없어졌지요...

만약 100만건이 입력된 데이터에서 오늘등록된 값을 구하려면 위에것은 예측불허이고

아래것은 0.0X초대에 결과를 가져올 수 있습니다....

JBBS0.9에서는 이걸 해결하지 못해서... 오늘 등록된 글을 처음에 뿌려 줄 수가 없었습니다..

왜? 느리니까....

하지만 생각해보니 방법이 있더군요... 다음버전에서는 첫화면에 당당히 오늘 등록된 글의 갯수를

뿌려 줄겁니다....

물론 활용방법은 끝이 없더군요....

###### 2.회원 1000만명을 수용하는 테이블을 설계해보자 ######

회원이 1000만명 정도 있다고 생각할때... 로그인과 패스워드를 일치하는 지 확인하기 위해서

아무리 인덱스가 걸려있다 하여도 빠른 결과를 얻기는 힘들겁니다...

마찬가지로 로그인 후 개인정보 수정 등 여러가지 면에서도 그렇구요...

당연히 관리자 툴에서 회원 전체 목록을 살펴보는 것두 힘듭니다..

인덱스가 걸려있지만 수십만페이지 다음부터는 인덱스 효과를 보기가 힘드니까요...

JBBS는 수동 디비즌 방법을 통해서 그 문제점을 해결했습니다....

역시 약간의 다른 방법으로 회원 프로그램에서도 문제를 해결할 수 있습니다....

일단 예를 들겠습니다...

활용은 직접 하시면 될 겁니다... 생각보다 쉬우니까요....

우선 회원 아이디로 정렬하고 회원 아이디를 무지 빠르게 찾기 위한 테이블 설계입니다...

회원 아이디 컬럼은 설계시 char형이나 varchar형으로 선언합니다...

따라서 인덱스를 다음과 같이 걸겠지요...

index 어쩌구(아이디컬럼)....

역시 단일 인덱스이기 때문에 회원데이터가 커지면 별 효과가 없습니다... 뒤로 갈수록...

그런데 아이디의 구성은

hatelove
sephi
a2cap 등오로 되어있지요...

만일 영문순으로 따로 테이블로 저장하면 어떨까요...? 맨 앞문자만 체크해서 이용하면 빠르겠지요?

당연하 얘기지만.. 별로 소용이 없는 방법이지요.. 테이블을 분할 해야 하므로...

하지만 똑같은 효과를 한테이블에서 낸다면 얼마나 좋겠습니까....

가능할까요?

당근 가능합니다....

왜일까요?

char나 varchar형은 컬럼의 일부분만을 인덱스로 지정할 수가 있기 때문입니다...

그럼 이제는 다 해결된겁니다....

index idpos(userid(1),userid)라구 결합 인덱스를 생성해 줍시다...

index idpos(userid(1),userid(2),userid)처럼 더 세분해 주어도 되고요...

당연히... 아이디의 최초문자를 1차 인덱스로 그리고 아이디전체를 2차인덱스로 가지게 되지요..

아이디별로 디비즌으로 구성된 테이블이 됩니다....

그리고 나머지 (즉 몇페이지시작은 누구부터.....) 부분은 이제 조금만 생각하면 되구요....

마찬가지로.. 이름순.. 기타 등등...

각 컬럼에 최적화된 설계를 통하면... 못할게 없게 되는 거지요...

이상입니다...

정렬방법은 스스로 생각해 보세요...

index namepos(name(1),name)식으로 결합인덱스로 잡아주세요....

그러면... 아이디의 첫문자를 1차인덱스로 잡아주기 때문에

1차 인덱스 키는 많아봐야 100개를 넘지 않습니다...

따라서 각 키가 관리해야 하는 자료수는 500만명을 지원한다고 해도 10만명이 넘지 않죠...

불러올때는

select * from 회원테이블 where id like '그룹아이디최초문자%' limit x,y 를 하시면 됩니다....

그럼 a-b의 경계값을 구하는 문제가 남아있지만... 그건 쉽게 해결 가능합니다...

로그인시에도 다음과 같이 하면 빠르겠죠?

select * from 회원테이블 where id like 'a%' and id = 'abcd' and passwd=password('1234')

###### 3.역순정렬에서도 기본 인덱스키를 그대로 이용하자... #######

내림차순으로 정렬되는 인덱스컬럼을 역시 인덱스를 그대로 사용하면서 역순정렬 할 수 있는 방법을 알려 드리겠습니다...

일단 예를 들어 설명하겠습니다..

회원 관리 테이블에서 아이디순 정렬을 예로 들겠습니다...

우선 인덱스가 걸려있으니 내림차순 정렬은 넘어가겠습니다...

하지만 올림차순 정렬에서는 order by desc 형식이 되니.. 아무 소용이 없습니다...

이건 데이터베이스로 해결하지 말구... 프로그래밍적으로 해결해 봅시다...

우선 총 페이지수를 구합니다... 여기서는 10페이지...

즉 1,2,3,4,5,6,7,8,9,10 이 있게 됩니다...

이걸 내부적으로 10,9,8,7,6,5,4,3,2,1 로 바꿔주면 간단히 해결됩니다...

현재 페이지는 = 마지막페이지-현재페이지+1 해주면 간단히 계산됩니다...

글구 원래 목록라인수를 10이라 해 주었을때.. 마지막 10페이지가 5개 밖에 없을때는

1페이지를 내부적으로 10페이지라 했으므로 1페이지를 5개라고 지정해 주면 됩니다...

이건 쉬운거니까.. 넘어가겠습니다... (지금의 마지막 라인수 구하는 거랑 똑같지요...)

그럼 어떻습니까? 역순정렬에 맞는 목록 그룹이 구해졌습니다.

즉, 역순 10000번째에서 10개... 하지만 이 10개는 아직은 내림차순 정렬이겠지요?

이 10개만 올림차순으로 바꿔주면 얘기는 끝난겁니다...

for ($i=마지막;$i>-1;$i--) {
mysql_data_seek($result,$i);
$row=mysql_fetch_row($result);
}

하면 간단히 끝납니다... 그럼.. 안뇽...

P.S.

저는 아직 올림차순.. 내림차순이 헤갈립니다...

저는 그거 백날 해도 헤갈리는 건 어쩔 수 없네요...

제발.. 정확히 좀 저에게 갈쳐 주세요...

하여간 위에서는

1,2,3,4 ==> 내림차순..
4,3,2,1 ==> 올림차순..

이라 썻으니까.. 그렇게만 이해해 주시고요...

가만 보니까 아무래도 거꾸로 쓴거 같은데.. 잘 모르겠네...

용어는 정확한거루 쓰시구요...

에공에공


출처 : php학교

http://www.phpschool.com/bbs2/inc_view.html?id=2208&code=tnt2&start=0&mode=search&field=body&search_name=&operator=and&period=all&category_id=&s_que=%BF%AA%BC%F8