>

10 개의 열이있는 Employee 테이블이 있습니다. 내 쿼리 where 절에서 column1과 column2 사용하고 있습니다. 두 열 모두에 색인을 만들면 즉 column1과 column2입니다. 두 인덱스를 모두 사용할 수 있습니까?

두 가지 접근 방식이 있습니다 :-

  • Approach1 : 첫 번째 where 절 인덱스가 사용되는 경우 및 두 번째 위치 인 경우 첫 번째 절로 반환 된 절 결과는 두 번째 색인 사용

  • Approach2 : 첫 번째 where 절이 사용되는 경우 행 ID를 가져 오십시오. 에 대한 두 번째 where 절 인덱스가 사용되고 행 ID를 가져오고 교차를 수행하십시오. 두 rowId 모두

인덱스는 어떻게 작동합니까?

업데이트 :-

MySQL 또는 Oracle 전략이 다른 경우 oracle을 DB로 고려하십시오

  • 답변 # 1

    Oracle의 경우 사용 된 술어의 선택성에 따라 달라집니다.

    한 술어의 선택성이 높고 다른 술어가 낮은 경우, 하나의 인덱스 만 사용되며 두 번째 술어는 테이블에서 필터링됩니다.

    여기서 실행 계획의 예

    select * from tab where a = 250 and b = 2;
    ---------------------------------------------------------------------------------------------
    | Id  | Operation                           | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                    |       |     1 |   207 |     4   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS BY INDEX ROWID BATCHED| TAB   |     1 |   207 |     4   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN                  | IDX_A |     1 |       |     3   (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("B"=2)
       2 - access("A"=250)
    
    

    A 의 술어  소수의 레코드 만 반환하고 (1, B의 조건자는 501 행을 반환) A 열의 인덱스 만 사용합니다.

    select 
    sum(case when a = 250 and b = 2 then 1 end) as cnt_ab,
    sum(case when a = 250  then 1 end) as cnt_a,
    sum(case when b = 2 then 1 end) as cnt_b
    from tab2;
        CNT_AB      CNT_A      CNT_B
    ---------- ---------- ----------
             1          1        501
    
    

    경우 두 인덱스가 모두 선택적인 것은 아니지만 술어의 조합은 선택적입니다Oracle은BITMAP 인덱스로 변환또는인덱스 조인. 선택된 액세스 경로는 테이블 통계 및 옵티 마이저 설정에 따라 다릅니다. 필자의 경우 비트 맵 변환을 얻었고 INDEX_JOIN 힌트를 사용하여 다른 계획을 얻었습니다. 인덱스 조인은 쿼리에서 인덱스에 정의 된 열만 반환하는 경우에만 가능합니다.

    select  * from tab where a = 105 and b = 23;
    
    

    조건 자 선택성

    select 
    sum(case when a = 105 and b = 23 then 1 end) as cnt_ab,
    sum(case when a = 105  then 1 end) as cnt_a,
    sum(case when b = 23 then 1 end) as cnt_b
    from tab;
        CNT_AB      CNT_A      CNT_B
    ---------- ---------- ----------
           200      21700     100000
    
    

    BITMAP으로 변환

    ---------------------------------------------------------------------------------------------
        | Id  | Operation                           | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
        ---------------------------------------------------------------------------------------------
        |   0 | SELECT STATEMENT                    |       |   829 |   167K|   434   (1)| 00:00:01 |
        |   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| TAB   |   829 |   167K|   434   (1)| 00:00:01 |
        |   2 |   BITMAP CONVERSION TO ROWIDS       |       |       |       |            |          |
        |   3 |    BITMAP AND                       |       |       |       |            |          |
        |   4 |     BITMAP CONVERSION FROM ROWIDS   |       |       |       |            |          |
        |*  5 |      INDEX RANGE SCAN               | IDX_A | 21552 |       |    45   (0)| 00:00:01 |
        |   6 |     BITMAP CONVERSION FROM ROWIDS   |       |       |       |            |          |
        |*  7 |      INDEX RANGE SCAN               | IDX_B | 21552 |       |   190   (1)| 00:00:01 |
        ---------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       5 - access("A"=105)
       7 - access("B"=23)
    
    

    인덱스 조인

    select /*+ INDEX_JOIN(a idx_a idx_b) */ a,b from tab where a = 105 and b = 23;
    ---------------------------------------------------------------------------------------
    | Id  | Operation          | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |                  |   829 |  5803 |   235   (1)| 00:00:01 |
    |*  1 |  VIEW              | index$_join$_001 |   829 |  5803 |   235   (1)| 00:00:01 |
    |*  2 |   HASH JOIN        |                  |       |       |            |          |
    |*  3 |    INDEX RANGE SCAN| IDX_A            |   829 |  5803 |    45   (0)| 00:00:01 |
    |*  4 |    INDEX RANGE SCAN| IDX_B            |   829 |  5803 |   190   (1)| 00:00:01 |
    ---------------------------------------------------------------------------------------    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter("A"=105 AND "B"=23)
       2 - access(ROWID=ROWID)
       3 - access("A"=105)
       4 - access("B"=23)
    
    

관련 자료

  • 이전 kubernetes - kubeadm 초기화 이미지 변경
  • 다음 javascript - 내용보다 앞에 나오는 Iframe의 스크롤 막대 스크롤바 높이를 내용의 높이로 설정하는 방법이 있습니까?