2013-05-16 3 views
-1

프로파일 링을 통해 기대했던 것보다 약간의 시간이 걸리므로 몇 가지 사항을 수정하고 싶습니다. 이 쿼리의 목적은 주어진 device_id에 대한 메시지 테이블에서 마지막 3 시간의 데이터를 가져 와서 마지막 메시지 수신 (시간 내림차순)으로 결과를 정렬하는 것입니다. 현재 데이터베이스에 복합 인덱스가있어 실제로 이상적이지는 않습니다. 모든 u 리 또는 u 리 구문이이 u 리를 빠르게하기 위해 권장 사항을 변경합니까?성능 Oracle 쿼리 튜닝

메시지 테이블 구조 :

열 :

id (auto incremented PK NUMBER(10)) 
device_id 
model_id 
state 
creation_date (DATE when row was inserted) 
time (unix time message was transmitted) 
//a bunch of other columns omitted 

인덱스 :

id 
device_id, model_id, state (composite index) 

쿼리

select * from messages where device_id='0-12345678' and creation_date > sysdate-3/24 order by time desc 
+0

쿼리 계획이란 무엇입니까? 복합 색인은 무엇입니까? 그것은'device_id, creation_date'에 복합 인덱스입니까? 이 쿼리는 몇 행을 반환합니까? 얼마나 빨리 실행됩니까? 얼마나 빨리 실행해야합니까? –

+1

'messages' 테이블에 몇 개의 행이 있습니까? 'device_id'는 얼마나 독특한가요? ('device_id','creation_date') 인덱스 화되지 않은 컬럼으로 데이터를 선택합니다. 쿼리가 느려지는 것은 당연한 일입니다. – npe

+0

메시지 테이블에는 6,354,837 개의 행이 있습니다. Device_id는 테이블 내에서 고유하지 않은 여러 메시지를 연결할 수 있습니다. 나는 색인을 만들지 않았고 이것이 내가 묻는 이유입니다. 색인이 변경되어야한다고 생각합니다. – c12

답변

3

Explain 계획을 게시하지 않았지만 전체 테이블 스캔 또는 인덱스 범위 스캔을 DEVICE_ID 아래로 수행 한 다음 전체 선택이 rowid에 의해 개별적으로 rowid에 액세스하는 것처럼 보입니다. 색인 및 DEVICE_ID은 고유하지 않습니다.

색인 작성에 대한 엄격한 규칙은 없지만 매우 일반적으로 카디널리티 (열에 고유 한 값의 수)의 순서대로 WHERE 절의 값을 색인화해야합니다. 일정 범위를 선택하면 DEVICE_ID, CREATION_DATE에 색인을 생성하는 것이 좋습니다.

select *도 사용하고 있습니다. 모든 열을 선택할 필요가없는 경우 don't do this. 디스크에서 더 많은 바이트를 읽고 네트워크를 통해 전송해야하는 바이트가 더 많습니다. DEVICE_ID, CREATION_DATETIME을 선택하는 경우 인덱스가이 세 열로 순서대로 변경되는 것이 좋습니다. 그래서 테이블을 전혀 건드리지 마십시오. 인덱스 만 선택하고 정렬 할 수 있습니다.

비즈니스 로직에서이 열 목록이 고유해야한다고 말하면 일반적인 색인과는 다른 고유 색인을 작성하십시오. 마지막으로, 이 아니면에 ORDER BY가 필요합니다. 그런 다음 추가 시간이 소요될 정렬을 제거합니다.

+0

원래 질문에서 복합 색인에 오타가 있었으며 device_id는 일부 또는 복합 색인입니다. 그게 당신의 대답을 바꾸나요? – c12

+0

속도를 높이고 싶지 않다면 ... 3 가지 별개의 일을 말합니다. 필요하지 않고 선택한 열의 수를 줄이면 순서를 제거합니다. _before_ 새 인덱스 만들기 인덱스를 유지 관리하고 디스크 공간을 차지합니다 (이 중 하나가 중요한 경우). 그것은 모두 "느린"방법과 "빠른"방법으로 만들고 싶습니다. – Ben

+0

@Ben ... 주문이 필요하며 모든 열이 필요합니다. – c12