select_string
SELECT String
SELECT로 String 데이터를 조회
SQL SELECT로 String 데이터를 조회합니다.
테스트 데이터 입력: Redis 명령으로 입력
Example
명령> | rms (ls) 기존 데이터 삭제 |
명령> | mset myint1 10 myint2 30 myint3 50 myint4 20 myint5 40 |
결과> | OK |
명령> | mset mynum1 12.3 mynum2 35.5 mynum3 54.4 mynum4 25.6 mynum5 49.8 |
결과> | OK |
명령> | mset mystr1 value10 mystr2 value30 mystr3 value50 mystr4 value20 mystr5 value40 |
결과> | OK |
SQL Insert 문으로 입력
Example
명령> | delete from string.*; 기존 데이터 삭제 |
명령> |
insert into string values('myint1', 10), ('myint2', 30), ('myint3', 50), ('myint4', 20), ('myint5', 40); |
결과> | 5 inserted |
명령> |
insert into string values('mynum1', 12.3), ('mynum2', 35.5), ('mynum3', 54.4), ('mynum4', 25.6), ('mynum5', 49.8); |
결과> | 5 inserted |
명령> |
insert into string values('mystr1', 'value10'), ('mystr2', 'value30'), ('mystr3', 'value50'), ('mystr4', 'value20'), ('mystr5', 'value40'); |
결과> | 5 inserted |
키 이름
SQL을 사용하려면 키 이름을 알파벳으로 시작해서 '_' 또는 숫자를 사용하시는 것이 편리합니다.
특수 기호를 사용하면 키 이름에 따옴표를 사용해야 합니다.
KEY_001, 'KEY-001', 'KEY:001'
SELECT * FROM STRING.MYINT*
String에서 key 시작하는 키와 값(value)를 조회한다.
Example
명령> | select * from string.myint*; key와 value 조회 |
명령> | select key,value from string.myint*; |
결과> |
0) key|value 1) myint1|10 2) myint2|30 3) myint3|50 4) myint4|20 5) myint5|40 |
명령> | select key from string.myint*; key만 조회 |
결과> |
0) key 1) myint1 2) myint2 3) myint3 4) myint4 5) myint5 |
명령> | select value from string.myint*; value만 조회 |
결과> |
0) value 1) 10 2) 30 3) 50 4) 20 5) 40 |
명령> | select * from string.myint1; 키 하나만 조회 |
결과> |
0) key|value 1) myint1|10 |
ORDER BY
정렬(sort)해서 보여준다.
Example
명령> | select * from string.myint* order by key; |
결과> |
0) key|value 1) myint1|10 2) myint2|30 3) myint3|50 4) myint4|20 5) myint5|40 |
명령> | select * from string.myint* order by value; |
결과> |
0) key|value 1) myint1|10 2) myint4|20 3) myint2|30 4) myint5|40 5) myint3|50 |
명령> | select * from string.myint* order by key desc; |
결과> |
0) key|value 1) myint5|40 2) myint4|20 3) myint3|50 4) myint2|30 5) myint1|10 |
명령> | select * from string.myint* order by value desc; |
결과> |
0) key|value 1) myint3|50 2) myint5|40 3) myint2|30 4) myint4|20 5) myint1|10 |
정렬(sort) 순서: 숫자 < 문자
Example
명령> | select * from string.my* order by value; |
결과> |
0) key|value 1) myint1|10 2) mynum1|12.3 3) myint4|20 4) mynum4|25.6 5) myint2|30 6) mynum2|35.5 7) myint5|40 8) mynum5|49.8 9) myint3|50 10) mynum3|54.4 11) mystr1|value10 12) mystr4|value20 13) mystr2|value30 14) mystr5|value40 15) mystr3|value50 |
LIMIT
출력 행 수를 제한한다.
Example
명령> | select * from string.my* limit 5; |
결과> |
0) key|value 1) myint1|10 2) myint2|30 3) myint3|50 4) myint4|20 5) myint5|40 |
명령> | select * from string.my* order by value limit 5; |
결과> |
0) key|value 1) myint1|10 2) mynum1|12.3 3) myint4|20 4) mynum4|25.6 5) myint2|30 |
LIMIT OFFSET
몇 행 건너 출력
Example
명령> | select * from string.my* limit 5 offset 3; --> 3행 건너 5행 출력 |
결과> |
0) key|value 1) myint4|20 2) myint5|40 3) mynum1|12.3 4) mynum2|35.5 5) mynum3|54.4 |
명령> | select * from string.my* limit 3, 5; --> 3행 건너 5행 출력 |
결과> |
0) key|value 1) myint4|20 2) myint5|40 3) mynum1|12.3 4) mynum2|35.5 5) mynum3|54.4 |
명령> | select * from string.my* order by value limit 5 offset 3; |
결과> |
0) key|value 1) mynum4|25.6 2) myint2|30 3) mynum2|35.5 4) myint5|40 5) mynum5|49.8 |
명령> | select * from string.my* order by value limit 3, 5; |
결과> |
0) key|value 1) mynum4|25.6 2) myint2|30 3) mynum2|35.5 4) myint5|40 5) mynum5|49.8 |
FUNCTIONS
COUNT()
개수를 조회한다.
Example
명령> | select count(*) from string.myint*; |
결과> |
0) count(*) 1) 5 |
VALCNT(key)
키가 가지고 있는 값(value)의 개수를 조회한다.
1) select key,valcnt(key) from list.*
2) select key,count(*) from list.* group by key
2번과 같이 group by를 사용하는 것보다 valcnt를 사용하는 것이 훨씬 속도가 빠르다.
VALCNT(key) = LEN(key) = CARD(key) 모두 같은 기능을 합니다.
Example
명령> | insert into list values('mylist1', 'value10', 'value30', 'value50', 'value20', 'value40'); |
명령> | insert into list values('mylist2', '110', '120', '130', '140', '150'); |
명령> | select key,valcnt(key) from list.my*; |
결과> |
0) key|valcnt(key) 1) myint1|5 2) myint2|5 |
명령> | select key,len(key) from list.my*; |
결과> |
0) key|len(key) 1) myint1|5 2) myint2|5 |
MAX(), MIN()
최댓값, 최솟값을 조회한다.
Example
명령> | select max(key) from string.myint*; |
결과> |
0) max(key) 1) myint5 |
명령> | select min(key) from string.myint*; |
결과> |
0) min(key) 1) myint1 |
명령> | select min(key),max(key) from string.myint*; |
결과> |
0) min(key)|max(key) 1) myint1|myint5 |
명령> | select min(value),max(value) from string.myint*; |
결과> |
0) min(value)|max(value) 1) 10|50 |
명령> | select max(key),max(value) from string.myint*; |
결과> |
0) max(key)|max(value) 1) myint5|50 |
이렇게 사용해도 됩니다. MAX(key)과 value를 같이 조회할 경우
Example
명령> | select max(key), value from string.myint*; |
결과> |
0) max(key)|value 1) myint5|40 |
명령> | select min(key), value from string.myint*; |
결과> |
0) min(key)|value 1) myint1|10 |
명령> | select max(value), key from string.myint*; |
결과> |
0) max(value)|key 1) 50|myint3 |
데이터 타입이 다른 경우 비교: 숫자 < 문자
Example
명령> | select min(value),max(value) from string.my*; |
결과> |
0) min(value)|max(value) 1) 10|value50 |
MAX(value1, value2), MIN(value1, value2)
Example
명령> | select max(10,20); |
결과> |
0) max(10,20) 1) 20 |
명령> | select key,value,max(value,25) from string.myint*; |
결과> |
0) key|value|max(value,25) 1) myint1|10|25 2) myint2|30|30 3) myint3|50|50 4) myint4|20|25 5) myint5|40|40 |
명령> | select key,value,min(value,25) from string.myint*; |
결과> |
0) key|value|min(value,25) 1) myint1|10|10 2) myint2|30|25 3) myint3|50|25 4) myint4|20|20 5) myint5|40|25 |
숫자 함수
SUM(), TOTAL(), AVG()
합계, 평균을 구한다.
Sum()과 total()의 차이점: Sum()은 대상이 정수일 경우 합계를 정수로 표현합니다.
Total()은 대상이 정수, 실수를 구분하지 않고 합계를 항상 실수로 표현합니다.
Example
명령> | select sum(value) from string.myint*; |
결과> |
0) sum(value) 1) 150 |
명령> | select avg(value) from string.myint*; |
결과> |
0) avg(value) 1) 30.0 |
문자, 숫자가 섞여 있을 경우에는 숫자만 계산한다.
Example
명령> | select sum(value) from string.my*; |
결과> |
0) sum(value) 1) 327.6 |
ABS() 절대값
절대값을 구한다.
Example
명령> | insert into string values('myint6', -15); |
결과> | OK |
명령> | select abs(value) from string.myint6; |
결과> |
0) abs(value) 1) 15 |
ROUND() 반올림
반올림한다. ROUND(숫자, [자릿수])
Example
명령> | select value,round(value) from string.mynum*; |
결과> |
0) value|round(value) 1) 12.3|12.0 2) 35.5|36.0 3) 54.4|54.0 4) 25.6|26.0 5) 49.8|50.0 |
문자 함수
LENGTH()
길이를 구한다. 이 경우 숫자도 문자로 취급해서 길이를 계산한다.
Example
명령> | select key,length(key),value,length(value) from string.my*; |
결과> |
0) key|length(key)|value|length(value) 1) myint1|6|10|2 중간 생략... 6) mynum1|6|12.3|4 중간 생략... 11) mystr1|6|value10|7 이하 생략... |
UPPER(), LOWER()
UPPER: 대문자로 변경한다.
LOWER: 소문자로 변경한다.
Example
명령> | insert into string values('key1', 'REDISGATE'), ('key2', 'Redis Enterprise'); |
결과> | OK |
명령> | select key,value,upper(value) from string.key*; |
결과> |
0) key|value|upper(value) 1) key1|REDISGATE|REDISGATE 2) key2|Redis Enterprise|REDIS ENTERPRISE |
명령> | select key,value,lower(value) from string.key*; |
결과> |
0) key|value|lower(value) 1) key1|REDISGATE|redisgate 2) key2|Redis Enterprise|redis enterprise |
LEFT(), RIGHT(), MID()
LEFT('문자열',숫자)
RIGHT('문자열',숫자)
MID('문자열',시작위치[,개수]) = SUBSTR()
Example
명령> | select key,value,left(value,5) from string.key*; |
결과> |
0) key|value|left(value,5) 1) key1|REDISGATE|REDIS 2) key2|Redis Enterprise|Redis |
명령> | select key,value,right(value,5) from string.key*; |
결과> |
0) key|value|right(value,5) 1) key1|REDISGATE|SGATE 2) key2|Redis Enterprise|prise |
명령> | select key,value,mid(value,6,5) from string.key*; |
결과> |
0) key|value|mid(value,6,5) 1) key1|REDISGATE|GATE 2) key2|Redis Enterprise| Ente |
명령> | select key,value,mid(value,6) from string.key*; |
결과> |
0) key|value|mid(value,6) 1) key1|REDISGATE|GATE 2) key2|Redis Enterprise| Enterprise |
REPLACE()
문자열 바꾸기: REPLACE('ABC','B','D') -> ADC
Example
명령> | select replace(value,'G','K') from string.key1; |
결과> |
0) replace(value,'G','K') 1) REDISKATE |
명령> | select replace(value,'GATE','DOOR') from string.key1; |
결과> |
0) replace(value,'GATE','DOOR') 1) REDISDOOR |
명령> | select replace(value,'GATE','GREAT') from string.key1; |
결과> |
0) replace(value,'GATE','GREAT') 1) REDISGREAT |
INSTR()
문자열이 포함된 첫 번째 순서: INSTR('ABC','B') -> 2
Example
명령> | select value,instr(value,'G') from string.key1; |
결과> |
0) value|instr(value,'G') 1) REDISGATE|6 |
명령> | select value,instr(value,'Ent') from string.key2; |
결과> |
0) value|instr(value,'Ent') 1) Redis Enterprise|7 |
LTRIM(), RTRIM(), TRIM()
LTRIM(값, [문자/문자열])
RTRIM(값, [문자/문자열])
TRIM(값, [문자/문자열])
Example
명령> | insert into string values('key3', ' REDIS '); |
결과> | OK |
명령> | select ltrim(value) from string.key3; |
결과> |
0) ltrim(value) 1) REDIS |
명령> | select char(39)||ltrim(value)||char(39) ltrim from string.key3; |
결과> |
0) ltrim 1) 'REDIS ' |
명령> | select char(39)||rtrim(value)||char(39) rtrim from string.key3; |
결과> |
0) rtrim 1) ' REDIS' |
명령> | select ltrim('ABCABCDDD','ABC'); |
결과> |
0) ltrim('ABCABCDDD','ABC') 1) DDD |
기타 함수
CHAR()
CHAR(십진수) -> 문자
Example
명령> | select char(65); |
결과> |
0) char(65) 1) A |
명령> | select char(65,66); |
결과> |
0) char(65,66) 1) AB |
명령> | select value,char(value) from string.myint5; |
결과> |
0) value|char(value) 1) 40|( |
HEX()
HEX(문자) -> 16진수
Example
명령> | select hex('A'); |
결과> |
0) hex('A') 1) 41 |
명령> | select hex('AB'); |
결과> |
0) hex('AB') 1) 4142 |
명령> | select value,hex(value) from string.myint1; |
결과> |
0) value|hex(value) 1) 10|3130 |
명령> | select value,hex(value) from string.key1; |
결과> |
0) value|hex(value) 1) REDISGATE|524544495347415445 |
RANDOM()
RANDOM(): -9223372036854775808 ~ +9223372036854775807 사이의 숫자
%(나머지), ABS()와 같이 사용
Example
명령> | select random(); |
결과> |
0) random() 1) 7603410276227502532 |
명령> | select random()%10; |
결과> |
0) random()%10 1) -6 |
명령> | select abs(random()%10); |
결과> |
0) abs(random()%10) 1) 6 |
RANDOMBLOB()
바이트
Example
명령> | select randomblob(1); |
결과> |
0) randomblob(1) 1) L |
명령> | select randomblob(2); |
결과> |
0) randomblob(2) 1) ym |
명령> | select hex(randomblob(1)); |
결과> |
0) hex(randomblob(1)) 1) 0C |
ZEROBLOB()
ZEROBLOB(숫자) -> hex 00 (NULL)
Example
명령> | select zeroblob(1); |
결과> |
0) zeroblob(1) 1) |
명령> | select hex(zeroblob(1)); |
결과> |
0) hex(zeroblob(1)) 1) 00 |
명령> | select quote(zeroblob(1)); |
결과> |
0) quote(zeroblob(1)) 1) X'00' |
QUOTE()
작은 따옴표로 둘러싼 값을 리턴한다.
Example
명령> | select value,quote(value) from string.key1; |
결과> |
0) value|quote(value) 1) REDISGATE|X'524544495347415445' |
TYPEOF(), TYPEOF2()
데이터 타입을 반환합니다.
TYPEOF(): integer, real, text, blob, null
TYPEOF2(): numeric, text, null -> 숫자, 문자로만 구분할 경우 유용하게 사용할 수 있습니다.
Example
명령> | select typeof(10),typeof(13.4),typeof('A'),typeof(randomblob(1)),typeof(NULL); |
결과> |
0) typeof(10)|typeof(13.4)|typeof('A')|typeof(randomblob(1))|typeof(NULL) 1) integer|real|text|blob|null |
명령> | select key,value,typeof(value),typeof2(value) from string.* where key in ('myint1','mynum1','mystr1'); |
결과> |
0) key|value|typeof(value)|typeof2(value) 1) myint1|10|integer|numeric 2) mynum1|12.3|real|numeric 3) mystr1|value10|blob|text |
WHERE TYPEOF()
Example
명령> | select * from string.* where typeof(value)='integer'; |
결과> |
0) key|value 1) myint1|10 2) myint2|30 3) myint3|50 4) myint4|20 5) myint5|40 |
명령> | select * from string.* where typeof(value)='real'; |
결과> |
0) key|value 1) mynum1|12.3 2) mynum2|35.5 3) mynum3|54.4 4) mynum4|25.6 5) mynum5|49.8 |
명령> | select * from string.* where typeof2(value)='numeric'; |
결과> |
0) key|value 1) myint1|10 2) myint2|30 3) myint3|50 4) myint4|20 5) myint5|40 6) mynum1|12.3 7) mynum2|35.5 8) mynum3|54.4 9) mynum4|25.6 10) mynum5|49.8 |
LIST TYPEOF()
Example
명령> | insert into list values('mylist4', 'AA', '10', 'BB', '20'); 테스트 데이터 입력 |
명령> | select * from list.mylist4 where typeof2(value)='numeric'; |
결과> |
0) key|value 1) mylist4|20 2) mylist4|10 |
명령> | select * from list.mylist4 where typeof2(value)='text'; |
결과> |
0) key|value 1) mylist4|BB 2) mylist4|AA |
명령> | delete from list.mylist4; 테스트 데이터 삭제 |
NULLIF()
NULLIF(X,Y) 두 값을 비교하여 같으면 NULL을 반환하고 같지 않으면 첫 번째 값을 리턴한다.
Example
명령> | select nullif('A','A'); |
결과> |
0) nullif('A','A') 1) (nil) |
명령> | select nullif('A','B'); |
결과> |
0) nullif('A','B') 1) A |
IFNULL()
IFNULL(X,Y) X가 Null이면 'Y'를 리턴하고, X가 Null이 아니면 X를 리턴한다.
Example
명령> | select ifnull(Null,'Y'); |
결과> |
0) ifnull(Null,'Y') 1) Y |
명령> | select ifnull('X','Y'); |
결과> |
0) ifnull('X','Y') 1) X |
CASE WHEN
CASE WHEN 조건 THEN ... ELSE ... END 처리
Example
명령> | select case when 1=2 then 'T' else 'F' end; |
결과> |
0) case when 1=2 then 'T' else 'F' end 1) F |
SUM(), TOTAL()
sum()은 계산 대상이 모두 정수일 경우 정수를 리턴한다. 실수가 있으면 실수를 리턴한다.
total()은 언제나 실수(real)를 리턴한다.
필드 또는 문자열 합치기 ||
key||'-'||value
Example
명령> | select key||'-'||value key_value from string.mystr1; |
결과> |
0) key_value 1) mystr1-value10 |
WHERE 조건
비교: =, <, <=, >, >=, !=, <>
키 비교
Example
명령> | select * from string.myint* where key <= 'myint3'; |
결과> |
0) key|value 1) myint1|10 2) myint2|30 3) myint3|50 |
명령> | select * from string.myint* where key > 'myint3'; |
결과> |
0) key|value 1) myint4|20 2) myint5|40 3) myint6|-15 |
값(value) 비교
Example
명령> | select * from string.myint* where value = 30; |
결과> |
0) key|value 1) myint2|30 |
명령> | select * from string.myint* where value >= 30; |
결과> |
0) key|value 1) myint2|30 2) myint3|50 3) myint5|40 |
명령> | select * from string.myint* where value < 30; |
결과> |
0) key|value 1) myint1|10 2) myint4|20 3) myint6|-15 |
명령> | select * from string.myint* where value != 30; |
결과> |
0) key|value 1) myint1|10 2) myint3|50 3) myint4|20 4) myint5|40 5) myint6|-15 |
AND, OR
Example
명령> | select * from string.myint* where value >= 20 and value < 40; |
결과> |
0) key|value 1) myint2|30 2) myint4|20 |
명령> | select * from string.myint* where value <= 20 or value > 40; |
결과> |
0) key|value 1) myint1|10 2) myint3|50 3) myint4|20 4) myint6|-15 |
BETWEEN
Example
명령> | select * from string.myint* where value between 20 and 40; |
결과> |
0) key|value 1) myint2|30 2) myint4|20 3) myint5|40 |
GLOB
*(별표), ?(물음표)
대소문자를 구분한다.
Example
명령> | select * from string.* where key glob '*1'; |
결과> |
0) key|value 1) key1|REDISGATE 2) myint1|10 3) mynum1|12.3 4) mystr1|value10 |
명령> | select * from string.key* where value glob 'Redis*'; |
결과> |
0) key|value 1) key2|Redis Enterprise |
LIKE
%(퍼센트), _(밑줄)
대소문자를 구분하지 않는다.
Example
명령> | select * from string.* where key like '%1'; |
결과> |
0) key|value 1) key1|REDISGATE 2) myint1|10 3) mynum1|12.3 4) mystr1|value10 |
명령> | select * from string.key* where value like 'redis%'; |
결과> |
0) key|value 1) key1|REDISGATE 2) key2|Redis Enterprise |
IN
Example
명령> | select * from string.* where key in ('myint3','mystr4','mystr5'); |
결과> |
0) key|value 1) myint3|50 2) mystr4|value20 3) mystr5|value40 |
명령> | select * from string.* where value in ('value10','value50'); |
결과> |
0) key|value 1) mystr1|value10 2) mystr3|value50 |
명령> | select * from string.* where value in (10,50); |
결과> |
0) key|value 1) myint1|10 2) myint3|50 |
NOT IN
Example
명령> | select * from string.myint* where key not in ('myint3','myint5'); |
결과> |
0) key|value 1) myint1|10 2) myint2|30 3) myint4|20 |
명령> | select * from string.myint* where key not in ('myint3','myint5','myint4'); |
결과> |
0) key|value 1) myint1|10 2) myint2|30 |
명령> | select * from string.myint* where value not in (10,50); |
결과> |
0) key|value 1) myint2|30 2) myint4|20 3) myint5|40 |
GROUP BY
Example
명령> | select left(key,5), count(*) from string.my* group by left(key,5); |
결과> |
0) left(key,5)|count(*) 1) myint|6 2) mynum|5 3) mystr|5 |
명령> | select left(key,5), min(key), max(key) from string.my* group by left(key,5); |
결과> |
0) left(key,5)|min(key)|max(key) 1) myint|myint1|myint6 2) mynum|mynum1|mynum5 3) mystr|mystr1|mystr5 |
명령> | select left(key,5), min(value), max(value) from string.my* group by left(key,5); |
결과> |
0) left(key,5)|min(value)|max(value) 1) myint|-15|50 2) mynum|12.3|54.4 3) mystr|value10|value50 |
명령> | select left(key,5), sum(value) from string.my* group by left(key,5); |
결과> |
0) left(key,5)|sum(value) 1) myint|135 2) mynum|177.6 3) mystr|0.0 |
GROUP BY HAVING
Example
명령> | select left(key,5), sum(value) from string.my* group by left(key,5) having sum(value) > 0; |
결과> |
0) left(key,5)|sum(value) 1) myint|135 2) mynum|177.6 |
성능 Performance
테스트 데이터 입력
redis-benchmark를 이용해서 총 30만개 키를 입력합니다.
keyA 10만개, keyB 10만개, keyC 10만개.
src/redis-benchmark -c 5 -n 100100 -r 1000000000 set keyA___rand_int__ valueA___rand_int__
src/redis-benchmark -c 5 -n 100100 -r 1000000000 set keyB___rand_int__ valueB___rand_int__
src/redis-benchmark -c 5 -n 100100 -r 1000000000 set keyC___rand_int__ valueC___rand_int__
Count 쿼리 성능
- select count(*) from string.key*; -> count: 300286 (27ms) opcode
- select left(key,4), count(*) from string.key* group by left(key,4); -> (147ms) opcode
1) keyA|100098
2) keyB|100093
3) keyC|100095 - select count(*) from string.keyA*; -> 100098 (14ms) opcode
- select count(*) from string.keyB*; -> 100093 (13ms) opcode
- select count(*) from string.keyC*; -> 100095 (13ms) opcode
- --> 성능면에서 keyA*, keyB*, keyC* 각각 쿼리를 실행하는 것이 group by 하는 것보다 빠릅니다.
- select count(*) from string.key* where key glob 'key[AB]*'; -> count: 200191 (69ms) opcode
- select count(*) from string.key* where key glob 'key[AC]*'; -> count: 200193 (71ms) opcode
- --> keyA*와 keyB*, keyA*와 keyC* 개수를 셀 때 위와 같이 glob를 사용할 수 있습니다.
Equal(=) 쿼리 성능
- --> key 비교일 경우 index scan으로 빠르게 찾습니다.
value 비교일 경우는 full value scan으로 지정한 범위의 키를 모두 scan 합니다. - select * from string.key* where key = 'keyA_000000071959'; -> (280us) index scan opcode
- select * from string.key* where value = 'valueA_000071729474'; -> (144ms) full value scan 30만개 비교 opcode
- select * from string.keyA* where value = 'valueA_000071729474'; -> (48ms) full value scan 10만개 비교 opcode
Glob, Like 쿼리 성능
- --> Glob는 대소문자를 구분한다. Like는 대소문자를 구분하지 않는다.
그러므로 key 검색에서도 like는 full scan하기 때문에 glob에 비교해서 속도가 느리다. - select * from string.key* where key glob 'keyA_00000000*'; -> (271us) index scan opcode
- select * from string.key* where key like 'keyA_00000000%'; -> (48ms) index full scan opcode
- select * from string.key* where value glob 'valueA_00000000*'; -> (148ms) full value scan opcode
- select * from string.keyA* where value glob 'valueA_00000000*'; -> (51ms) full value scan opcode
- select * from string.key* where value like 'valueA_00000000%'; -> (154ms) full value scan opcode
- select * from string.keyA* where value like 'valueA_00000000%'; -> (53ms) full value scan opcode
- --> Value 비교는 key에서 value를 찾는 과정이 한 번 더 있기 때문에 key 비교보다 속도가 느리다.
Order by 쿼리 성능
- --> key에 대한 order by는 index가 있으므로 속도가 빠르다.
value는 index가 없으므로 쿼리 실행 시 sort해야 되므로 속도가 느리다.
예제 쿼리는 키가 5개이므로 속도에 차이가 없어 보인다. - select * from string.myint* order by key; -> (271us) index scan opcode
- select * from string.myint* order by value; -> (269us) full value scan, sort opcode
- select * from string.myint* order by key desc; -> (268us) index scan opcode
- select * from string.myint* order by value desc; -> (266us) full value scan, sort opcode
Min(), max() 함수 성능
- --> min(key) 또는 max(key)만 사용했을 경우에는 속도가 빠르다,
하지만 min(key)과 max(key)를 같이 사용하면 full key scan하므로 속도가 느리다. - --> value에 대한 min/max는 full value scan하므로 속도가 느리다.
- select min(key) from string.keyA*; -> (239us) index scan opcode
- select max(key) from string.keyA*; -> (250us) index scan opcode
- select min(key),max(key) from string.keyA*; -> (22ms) full key scan opcode
Limit 성능
- --> 50001번 째부터 10건의 데이터를 조회한다.
key는 index scan을 하므로 속도가 빠르다.
value는 실행 시 memory sort 후 처리하므로 느리다. - select * from string.keyA* order by key limit 50000, 10; -> (8ms) index scan opcode
- select * from string.keyA* order by value limit 50000, 10; -> (176ms) full value scan opcode
Between 성능
- --> key에 대한 between, 등호, 부등호 쿼리는 index를 사용하므로 속도가 빠르다.
- --> Not between은 index를 사용하지 못하므로 속도가 느리다.
- select * from string.keyA* where key between 'keyA_000462294115' and 'keyA_000462376609'; -> (382us) index scan opcode
- select * from string.keyA* where key >= 'keyA_000462294115' and key <= 'keyA_000462376609'; -> (389us) index scan opcode
In 성능
- --> key에 대한 in은 속도가 빠르다.
- --> Not in은 index를 사용하지 못하므로 속도가 느리다.
- select * from string.keyA* where key in ('keyA_000462294115', 'keyA_000462376609'); -> (296us) index scan opcode
OPCODE
select count(*) from string.key*;
select left(key,4), count(*) from string.key* group by left(key,4);
select count(*) from string.keyA*;
select count(*) from string.keyB*;
select count(*) from string.keyC*;
select count(*) from string.key* where key glob 'key[AB]*';
select count(*) from string.key* where key glob 'key[AC]*';
select * from string.key* where key = 'keyA_000000071959';
select * from string.key* where value = 'valueA_000071729474';
select * from string.keyA* where value = 'valueA_000071729474';
select * from string.key* where key glob 'keyA_00000000*';
select * from string.key* where key like 'keyA_00000000%';
select * from string.key* where value glob 'valueA_00000000*';
select * from string.keyA* where value glob 'valueA_00000000*';
select * from string.key* where value like 'valueA_00000000%';
select * from string.keyA* where value like 'valueA_00000000%';
select * from string.myint* order by key; -> index scan
select * from string.myint* order by value; -> full value scan, sort
select * from string.myint* order by key desc; -> index scan
select * from string.myint* order by value desc; -> full value scan, sort
select min(key) from string.keyA*; -> index scan
select max(key) from string.keyA*; -> index scan
select min(key),max(key) from string.keyA*; -> full key scan
select * from string.keyA* order by key limit 50000, 10;
select * from string.keyA* order by value limit 50000, 10;
select * from string.keyA* where key between 'keyA_000462294115' and 'keyA_000462376609';
select * from string.keyA* where key >= 'keyA_000462294115' and key <= 'keyA_000462376609';
select * from string.keyA* where key in ('keyA_000462294115', 'keyA_000462376609'); -> index scan
<< Select Intro | Select String | Select List >> |
---|