2012-03-14 2 views
1

수행하고 싶지 않은 쿼리가 있습니다. 거의 모든 페이지에서 바닥 글에 4 명의 무작위 교사와 관련 데이터 (이름, 아바타 및 제공하는 코스 수)를 표시합니다.Oracle에서 3 개의 조인을 사용하는이 쿼리를 향상 시키거나 "partition over"를 사용합니까?

Oracle에서이 쿼리의 실행 속도를 어떻게 향상시킬 수 있습니까? 나는 파티션을보고 있었고 다른 파티션과 파티션을 사용하고있었습니다. 나는 mySQL 배경을 가지고 있으며 오라클을 최대한으로 사용하지는 않을 것입니다.

I가 다음과 같은 테이블 구조 :

tutor_profiles: 
    id 
    user_id (FK users) 

users: 
    id 
    username 
    avatar_id (FK files) 

courses: 
    id 
    tutor_id (FK tutor_profiles) 
    description 
    ... 

    files 
     id 
     file_uri 

`

그리고이 쿼리가 : 스타터

SELECT * FROM 
    (SELECT inner_query.*, rownum rnum 
    FROM (
     SELECT tutor_profiles.id AS "tutor_id" 
      , tutor_profiles.full_name AS "full_name" 
      , files.file_uri as "file_uri" 
      , files.id AS file_id 
      , tutor_profiles.user_id 
      , count(distinct courses.id) AS "course_count" 
     FROM tutor_profiles 
      LEFT JOIN users ON users.id = tutor_profiles.user_id 
      LEFT JOIN files ON files.id = users.avatar_id 
      LEFT JOIN courses ON tutor_profiles.id = courses.tutor_id 
     GROUP BY tutor_profiles.id, tutor_profiles.full_name, tutor_profiles.user_id, files.file_uri, files.id 
     ORDER BY dbms_random.VALUE 
    ) inner_query 
    WHERE rownum <= 4) 
+0

수행 할 쿼리는 무엇입니까? – Luke101

+0

쿼리는 데이터베이스에서 얼마나 많은 과목을 가지고 있는지, 자신의 프로필 아바타 – Mythriel

답변

2

- 방법 인덱스가 있습니까?

당신은 (어쩌면 그 전에 실제로) 그 이후

users.id 
files.id 
tutor_profiles.user_id 
tutor_profiles.id 
courses.tutor_id 
users.avatar_id 

에 인덱스를 가져야한다, (가) 계획 보여주는 설명 무엇인가?

대략 테이블에 몇 개의 레코드가 있습니까?

+0

500 레코드를 가지고있는 4 명의 무작위 튜터를 얻으려고합니다. 인덱스가 없으며 오라클과 함께 PHP를 사용하고 있습니다. 어쨌든 memcache를 사용하여 결과를 캐시합니다. – Mythriel

+0

4 명의 무작위 교사 ("교사"가 아닌 다른 요구 사항이있을 수 있음)를 생성 한 다음 필요로하는 데이터를 생성하는 것이 훨씬 낫습니다. –

+0

Oracle의 SQL * Developer 제품을 사용하고 있습니까? 워크 시트 편집기에 EXPLAIN PLAN 버튼이 있습니다. –

2

앤디 핀켄 슈타 트 (Andy Finkenstadt)는 4 명의 무작위 교사를 선택하고 남은 결과 집합에서 4 개의 무작위 값을 선택하는 것이 더 나을 것이라고 제안했습니다. 즉, dbms_random.value을 두 번 주문했음을 의미합니다 (악화되는 경우). 주문하는 데이터 세트가 훨씬 작다는 것을 의미합니다.

또한 Randy's answer과 같은 인덱스가 있는지 확인해야합니다. 이 결코이 원인이 여분의 번거 로움 가치가이에 대한 매우 좋은 이유가없는

애완 동물 초조의 "가 맡았다 열 이름을 생성합니다. 처음에는 거꾸로 쉼표로 참조해야합니다.

당신이 count과 선택에 distinct을 추가해야합니다 일을 속도를 count(distinct c.id) over()으로 count(distinct c.id)을 대체 할 수 분석 함수를 사용하려고합니다. 즉, 모든 행에 대해 distinctid으로 계산됩니다. partition by 절을 추가하면 파티션에있는 모든 항목에 대해이 개수를 계산할 수 있습니다. group by도 완전히 제거해야합니다.

필자는 불필요한 하위 선택을 제거했습니다.

select * 
    from (select tp.id as tutor_id 
       , tp.full_name as full_name 
       , f.file_uri as file_uri 
       , f.id AS file_id 
       , tp.user_id 
       , count(distinct c.id) as course_count 
      from (select * 
        from (select id 
           , full_name 
           , user_id 
          from tutor_profiles 
          order by dbms_random.value) 
        where rownum <= 4) tp 
      left outer join users u 
      on u.id = tp.user_id 
      left outer join files f 
      on f.id = u.avatar_id 
      left outer join courses c 
      on tp.id = c.tutor_id 
      group by tp.id, tp.full_name, tp.user_id, f.file_uri, f.id 
      order by dbms_random.value) 
where rownum <= 4 
+0

첫 번째 테이블의 무작위 샘플을 사용하여 성능을 향상시킬 수도 있습니다. 예 :'from tutor_profiles sample (5)'. 올바른 샘플 퍼센트를 선택하는 것은 까다로울 수 있습니다. 작은 백분율로 가능한 한 적은 데이터를 검색하기를 원하지만 항상 4 행 이상을 확보 할만큼 충분히 큰 숫자가 필요합니다. 그러나 다른 한편으로 행 수가 매우 적 으면 한 번에 한 블록 씩 읽는 대신 전체 테이블 스캔을하는 것이 더 빠를 수 있습니다. –

+0

aaa ...이 쿼리는 내 첫 번째 쿼리보다 훨씬 더 실행됩니다. – Mythriel

+0

@Mythriel, 여섯 번째 단어는 _may_ :-)입니다. 캐시가 처음 실행 한 후에 만 ​​작동하는 색인을 생성 했습니까? – Ben

관련 문제