2011년 11월 2일 수요일
[Oracle] 튜닝보고서
> 사용자가 많지 않은데 오라클+톰캣이 느린경우. 특별한 쿼리나 스크립트가 돌지 않은 상황이다.
* 힌트
> i/o 사용량을 확인하는 쿼리로 확인 결과 엄청난(?) 양의 쿼리가 필요없이 DB에서 돌고 있다.
> 쿼리
select xx.*
from
(select
a.ACTION action_a
,a.ACTION_HASH action_hash_a
,a.ADDRESS
,a.BUFFER_GETS
,a.CHILD_LATCH
,a.COMMAND_TYPE
,a.CPU_TIME
,a.DISK_READS
,a.ELAPSED_TIME
,a.EXECUTIONS
,a.FETCHES
,a.FIRST_LOAD_TIME
,a.HASH_VALUE
,a.INVALIDATIONS
,a.IS_OBSOLETE
,a.KEPT_VERSIONS
,a.LOADED_VERSIONS
,a.LOADS
,a.MODULE MODULE_a
,a.MODULE_HASH MODULE_HASH_a
,a.OPEN_VERSIONS
,a.OPTIMIZER_MODE
,a.PARSE_CALLS
,a.PARSING_SCHEMA_ID
,a.PARSING_USER_ID
,a.PERSISTENT_MEM
,a.ROWS_PROCESSED
,a.RUNTIME_MEM
,a.SERIALIZABLE_ABORTS
,a.SHARABLE_MEM
,a.SORTS
,a.SQL_TEXT
,a.USERS_EXECUTING
,a.USERS_OPENING
,a.VERSION_COUNT
,b.ACTION
,b.ACTION_HASH
,b.AUDSID
,b.CLIENT_IDENTIFIER
,b.CLIENT_INFO
,b.COMMAND
,b.CURRENT_QUEUE_DURATION
,b.FAILED_OVER
,b.FAILOVER_METHOD
,b.FAILOVER_TYPE
,b.FIXED_TABLE_SEQUENCE
,b.LAST_CALL_ET
,b.LOCKWAIT
,b.LOGON_TIME
,b.MACHINE
,b.MODULE
,b.MODULE_HASH
,b.OSUSER
,b.OWNERID
,b.PADDR
,b.PDDL_STATUS
,b.PDML_ENABLED
,b.PDML_STATUS
,b.PQ_STATUS
,b.PREV_HASH_VALUE
,b.PREV_SQL_ADDR
,b.PROCESS
,b.PROGRAM
,b.RESOURCE_CONSUMER_GROUP
,b.ROW_WAIT_BLOCK#
,b.ROW_WAIT_FILE#
,b.ROW_WAIT_OBJ#
,b.ROW_WAIT_ROW#
,b.SADDR
,b.SCHEMA#
,b.SCHEMANAME
,b.SERIAL#
,b.SERVER
,b.SID
,b.SQL_ADDRESS
,b.SQL_HASH_VALUE
,b.STATUS
,b.TADDR
,b.TERMINAL
,b.TYPE
,b.USER#
,b.USERNAME
from v$sqlarea A,
v$session B
where A.disk_reads > 10000
and A.ADDRESS = B.SQL_ADDRESS(+)
AND A.HASH_VALUE = B. SQL_HASH_VALUE(+)
order by A.disk_reads desc) xx
where rownum < 30
* 해결방법
> 모든 jsp 에서 참조하고 있는 의미없는 쿼리를 로그인 시 1회 로드하여 세션에 저장하도록 변경
* 현재 값과 튜닝 후 예상 값(결과)
>
2011년 11월 1일 화요일
[Oracle] 오라클 메모리(1)
* share pool, database buffer cache, redo log buffer, java pool, large pool 이 있는 시스템 영역
PGA - program global area
* 한 프로세스 혹은 쓰레드를 위해 개별적으로 할당되는 공간
* pga 확인 쿼리 - select * from v$process
UGA - user global area
* 전용서버모드 dedicated server 에서만 존재하며 shared server 모드에서는 PGA = UGA 이다.
[Oracle] DB 모니터링 쿼리
- 쿼리가 optimize 가 제대로 되지 않아서 SQL cache 안에서 쉽게 사라지지 않는 쿼리를 확인 하는 쿼리 (1)
SELECT Disk_Reads DiskReads, Executions, SQL_Text SQLText
FROM
(
SELECT Disk_Reads, Executions, LTRIM(SQL_Text) SQL_Text,
Operation, Options,
Row_Number() OVER
(Partition By sql_text ORDER BY Disk_Reads * Executions DESC)
KeepHighSQL
FROM
(
SELECT Avg(Disk_Reads) OVER (Partition By sql_text) Disk_Reads,
Max(Executions) OVER (Partition By sql_text) Executions,
sql_text, p.operation,p.options
FROM v$sql t, v$sql_plan p
WHERE t.hash_value=p.hash_value AND p.operation='TABLE ACCESS'
AND p.options='FULL' AND p.object_owner NOT IN ('SYS','SYSTEM')
AND t.Executions > 1
)
ORDER BY DISK_READS * EXECUTIONS DESC
)
WHERE KeepHighSQL = 1
AND rownum <=30;
- 쿼리가 optimize 가 제대로 되지 않아서 SQL cache 안에서 쉽게 사라지지 않는 쿼리를 확인 하는 쿼리 (2)
(SELECT
sql_text,
child_number,
disk_reads,
executions,
first_load_time,
last_load_time
FROM v$sql
ORDER BY elapsed_time DESC)
WHERE ROWNUM < 10;
- 특정 DISK_READS 횟수 이상만큼의 쿼리를 보는 쿼리 - 문제가 되었던 getsesseioninfo.jsp 는 141484750 회 읽혔음 OTL
SELECT parsing_user_id, executions, sorts, command_type, disk_reads,
sql_text
FROM v$sqlarea
WHERE disk_reads > &&access_level
ORDER BY disk_reads desc;
- V$SQL_WORKAREA_ACTIVE, V$SQL_WORKAREA, V$SQL 뷰를 이용하여 현재 시스템에서 할당된 실행 영역 중 top 10을 찾습니다.
FROM ( SELECT *
FROM ( SELECT workarea_address, actual_mem_used wasize
FROM v$sql_workarea_active
ORDER BY actual_mem_used desc)
WHERE ROWNUM <= 10 ) top_ten,
v$sql_workarea w, v$sql c
WHERE w.workarea_address = top_ten.workarea_address
AND c.address = w.address
AND c.child_number = w.child_number
AND c.hash_value = w.hash_value;
- V$SQL_WORKAREA 뷰를 통해서 다음과 같이 SQL 실행 메모리를 가장 많이 필요로 하는
top 10 실행 영역을 구할 수 있다.
FROM ( SELECT workarea_address, operation_type, policy, estimated_optimal_size
FROM v$sql_workarea
ORDER BY estimated_optimal_size DESC )
WHERE ROWNUM <= 10;
- 커서가 열린 뒤 닫히지 않아서 메모리가 반환되지 못하는 경우
- current cursor 가 몇백 몇천개인지 확인할 것
sum(decode(name,'recursive calls',value)) "Recursive Calls",
sum(decode(name,'opened cursors cumulative',value)) "Opened Cursors",
sum(decode(name,'opened cursors current',value)) "Current Cursors"
FROM v$session ss, v$sesstat se, v$statname sn, v$process p
WHERE se.statistic# = sn.statistic#
AND ( name like '%opened cursors current%'
OR name like '%recursive calls%'
OR name like '%opened cursors cumulative%')
AND se.sid = ss.sid
and ss.paddr=p.addr
AND ss.username is not null
GROUP BY ss.username , se.sid , p.spid
order by "Current Cursors" asc
- 같은 쿼리지만 쉐어할 수 없어서 다른 쿼리로 인식되는 경우 카운트
- PGA/UGA 사용량을 산출하는 쿼리
ttitle '**********< Program Global Area >**********'
ttitle '1. Current pga, uga session memory'
select a.sid, a.username, substr(a.program, 1, 25) as pgm, a.terminal,
max(decode(c.name, 'session pga memory', trunc(value/1000)||'K', 0)) pga,
max(decode(c.name, 'session uga memory', trunc(value/1000)||'K', 0)) uga
from v$session a, v$sesstat b, v$statname c
where a.sid = b.sid
and b.statistic# = c.statistic#
and c.name like 'session%'
group by a.sid, a.username, substr(a.program, 1, 25), a.terminal;
ttitle '2. Sum of current pga, uga session memory'
select 'Current PGA, UGA session memory SUM:' as sum,
sum(decode(c.name, 'session pga memory', trunc(value/1000),0))||'K' pga_sum,
sum(decode(c.name, 'session uga memory', trunc(value/1000),0))||'K' uga_sum
from v$session a, v$sesstat b, v$statname c
where a.sid = b.sid
and b.statistic# = c.statistic#
and c.name like 'session%';
ttitle '3. Max(peak) pga, pga session memory'
select a.sid, a.username, substr(a.program, 1, 25) as pgm, a.terminal,
max(decode(c.name, 'session pga memory max', trunc(value/1000)||'K', 0)) pga_max,
max(decode(c.name, 'session uga memory max', trunc(value/1000)||'K', 0)) uga_max
from v$session a, v$sesstat b, v$statname c
where a.sid = b.sid
and b.statistic# = c.statistic#
and c.name like 'session%'
group by a.sid, a.username, substr(a.program, 1, 25), a.terminal;
ttitle '4. Sum of max(peak) pga, uga session memory'
select 'Max(peak) PGA, UGA session memory SUM:' as sum,
sum(decode(c.name, 'session pga memory max', trunc(value/1000), 0))||'K' pga_m_sum,
sum(decode(c.name, 'session uga memory max', trunc(value/1000), 0))||'K' uga_m_sum
from v$session a, v$sesstat b, v$statname c
where a.sid = b.sid
and b.statistic# = c.statistic#
and c.name like 'session%';
- i/o 사용량이 많은 순서대로 프로세스를 확인하는 쿼리
B.sid, B.serial#
from v$sqlarea A,
v$session B
where A.disk_reads > 10000
and A.ADDRESS = B.SQL_ADDRESS(+)
AND A.HASH_VALUE = B. SQL_HASH_VALUE(+)
order by A.disk_reads desc;
- 메모리 사용량이 많은 순서대로 프로세스 확인(자세한 확인이 필요함...)
D.sid "SID",
D.username "Oracle User",
D.program "Program",
D.module "Module",
D.status "Status",
D.type "Type",
D.server "Connection",
to_char(D.logon_time,'YYYY-MM-DD HH24:MI:SS') LOGON_TIME,
D.osuser OS_USER ,
decode(D.lockwait,null,'','Blocking') LLOCK,
decode(D.taddr,null,'','TX') TRAN,
A.User_Name,
D.machine MACHINE,
B.Disk_Reads,
B.Buffer_Gets,
B.Rows_Processed,
C.SQL_Text,
A.Address
From V$Open_Cursor A,
V$SQLArea B,
V$SQLText C,
sys.v_$session D
Where 1=1
AND B.ADDRESS = D.SQL_ADDRESS
AND B.HASH_VALUE = D.SQL_HASH_VALUE
And A.Address = C.Address
;
- UGA/PGA 확인 쿼리
- 사용량이 peak 일때 돌려보자
SELECT
s.sid sid
, lpad(s.username,12) oracle_username
, lpad(s.osuser,9) os_username
, s.program session_program
, lpad(s.machine,8) session_machine
, (select ss.value from v$sesstat ss, v$statname sn
where ss.sid = s.sid and
sn.statistic# = ss.statistic# and
sn.name = 'session pga memory') session_pga_memory
, (select ss.value from v$sesstat ss, v$statname sn
where ss.sid = s.sid and
sn.statistic# = ss.statistic# and
sn.name = 'session pga memory max') session_pga_memory_max
, (select ss.value from v$sesstat ss, v$statname sn
where ss.sid = s.sid and
sn.statistic# = ss.statistic# and
sn.name = 'session uga memory') session_uga_memory
, (select ss.value from v$sesstat ss, v$statname sn
where ss.sid = s.sid and
sn.statistic# = ss.statistic# and
sn.name = 'session uga memory max') session_uga_memory_max
FROM
v$session s
ORDER BY session_pga_memory DESC
2011년 10월 30일 일요일
[android] Notepad 예제 중 XML 레이아웃
아래글은
http://developer.android.com/resources/tutorials/notepad/notepad-ex1.html 중
Step 4를 제 기준대로 번역/설명한 내용임
<!--?xml version="1.0" encoding="utf-8"?-->
<linearlayout android="http://schemas.android.com/apk/res/android"
layout_width="wrap_content"
layout_height="wrap_content">
<listview id="@android:id/list"
layout_width="wrap_content"
layout_height="wrap_content">
<textview id="@android:id/empty"
layout_width="wrap_content"
layout_height="wrap_content"
text="@string/no_notes">
</textview>
</listview>
</linearlayout>
- The ListView and TextView can be thought as two alternative views, only one of which will be displayed at once. ListView will be used when there are notes to be shown, while the TextView (which has a default value of "No Notes Yet!" defined as a string resource in res/values/strings.xml) will be displayed if there aren't any notes to display.
- (번역) ListView와 TextView는 서로 보완대치된다고 생각하면 된다. 오직 한개의 뷰만 화면에 보여질 뿐이다. ListView는 노트의 값이 있을때 보여지게 되고 만약 한개의 값도 존재하지 않으면 TextView(res/values/strings.xml 파일안에 디폴트 값이 'No Notes Yet'으로 설정되어있음)가 보여지게된다.
- The list and empty IDs are provided for us by the Android platform, so, we must prefix the id with android: (e.g., @android:id/list).
- (번역) 리스트와 empty ID들은 안드로이드 플랫폼에 의해 자동으로 제공된다. 그러므로 우리는 반드시 android와 함께 id를 선언해야한다.(예 @android:id/list)
- The View with the empty id is used automatically when the ListAdapter has no data for the ListView. The ListAdapter knows to look for this name by default. Alternatively, you could change the default empty view by using setEmptyView(View) on the ListView.
- (번역) empty id가 선언된 뷰는 ListAdapter에 데이터가 없을때 자동으로 사용된다. ListAdapter는 자동으로 찾기 위해 기본적으로 이 이름을 알고 있다.참고로 default empty view는 ListView에서 setEmptyView(View)를 설정함으로 변경할 수 있다
- More broadly, the android.R class is a set of predefined resources provided for you by the platform, while your project's R class is the set of resources your project has defined. Resources found in the android.R resource class can be used in the XML files by using the android: name space prefix (as we see here).
- (번역) 흔히 android.R 클래스는 플랫폼에서 기본적으로 제공하는 리소스들을 선언하는 클래스이다. 당신의 프로젝트에서 사용되어지는 R class는 프로젝트에서 정의하는 리소스들의 집합체이다. R 클래스 안에서 보여지는 리소스들은 XML파일 안에서 android:name space prefix(이곳에 보여지는대로) 형태로 정의해서 사용될 수 있다.
2011년 10월 20일 목요일
[JAVA] 인코딩에 관하여
UTF8로 설정방법
1. 자바파일 자체의 인코딩
> 이클립스 property - resource - text file encoding
2. 톰캣 구동 시 인코딩
> 환경 설정에서 JAVA_TOOL_OPTIONS 을 다음 파라미터로 추가한다. -Dfile.encoding=UTF8
> 구동/셧다운 시 Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8 이 보이면 성공
3. 서블릿에서 request/response 시 인코딩 세팅
> request.setCharacterEncoding("UTF-8");
4. JSP 파일에서 인코딩 선언
> <%@ page contentType="text/html;charset=xxx"%>
> 확인방법 ; <%= System.getProperty("file.encoding") %>
2011년 10월 15일 토요일
2011년 10월 6일 목요일
[jQuery] each loop
$("input[name='chk_item']").each( function (idx){
$(this).eq(idx).val()
});