복붙노트

[SQL] SQL 쿼리는 여러 테이블을 조인 - 너무 느린 (8 표)

SQL

SQL 쿼리는 여러 테이블을 조인 - 너무 느린 (8 표)

(내 MySQL의 기술의 매우 아마추어) : 내가 다른 응용 프로그램에서 사용하는 인덱스를 생성하기 위해 하나에 8 개 개의 테이블을 조인하기 위해 노력하고있어, 내 쿼리는 같다

SELECT t1_id, t2_name, t3_name, t4_name, t5_name, 
       t6_name, t7_name, t8_name, t9_name 
FROM t1 
  LEFT JOIN t2 ON (t1_id = t2_id) 
  LEFT JOIN t3 ON (t3_id = t1_id) 
  LEFT JOIN t4 ON (t4_id = t1_id)
  LEFT JOIN t5 ON (t5_id = t1_id)
  LEFT JOIN t6 ON (t6_id = t1_id) 
  LEFT JOIN t7 ON (t7_id = t1_id)
  LEFT JOIN t8 ON (t8_id = t1_id)
  LEFT JOIN t9 ON (t9_id = t1_id)

내가 그것을 속도를 어떤 방법으로 그것을 실행할 때 난 쿼리 결과를 볼 수없는 이유는 무엇입니까? :) 도움의 종류에 감사하지만, 더 나은 하나 개의 쿼리 (외부 응용 프로그램 규칙)이 될 것

사전에 감사합니다

해결법

  1. ==============================

    1.나는 몇 룩업 테이블 색인 모든 ID 필드와 큰 테이블에 합류와 비슷한 문제가 있었다. (가) 쿼리 시간 실행에 조인의 효과를 모니터링하기 위해, 나는이 추가 테이블마다 가입 추가 (처음 100 개 행 제한) 내 쿼리를 여러 번 실행. 12 개 테이블을 조인 후, 쿼리 실행 시간에 큰 변화가없는 것으로 나타났다. 그 때까지는 나는 실행 시간은 1 초에 뛰어 13 테이블에 합류했다; 14 테이블 사초, 15 테이블 20 초, 16 90초.

    나는 몇 룩업 테이블 색인 모든 ID 필드와 큰 테이블에 합류와 비슷한 문제가 있었다. (가) 쿼리 시간 실행에 조인의 효과를 모니터링하기 위해, 나는이 추가 테이블마다 가입 추가 (처음 100 개 행 제한) 내 쿼리를 여러 번 실행. 12 개 테이블을 조인 후, 쿼리 실행 시간에 큰 변화가없는 것으로 나타났다. 그 때까지는 나는 실행 시간은 1 초에 뛰어 13 테이블에 합류했다; 14 테이블 사초, 15 테이블 20 초, 16 90초.

    예를 들어, 조인의 Keijro의 제안 대신에 상관 하위 쿼리를 사용하는

    SELECT t1_id, 
            (select t2_name from t2 where t1_id = t2_id), 
            (select t3_name from t3 where t1_id = t3_id), 
            (select t4_name from t4 where t1_id = t4_id), 
            (select t5_name from t5 where t1_id = t5_id), 
            (select t6_name from t6 where t1_id = t6_id), 
            (select t7_name from t7 where t1_id = t7_id), 
            (select t8_name from t8 where t1_id = t8_id), 
            (select t9_name from t9 where t1_id = t9_id)  FROM t1
    

    극적으로 개선 된 쿼리 성능을 제공합니다. 실제로 하위 쿼리는 쿼리 (쿼리가 거의 instanteous했다)을 실행하는 시간을 길게하는 것 같지 않았어요.

    나는 상관 서브 쿼리 조인보다 더 수행 생각으로 조금 놀랄입니다.

  2. ==============================

    2.테이블에있는 데이터의 양에 따라에 가입되고있는 컬럼에 위치 인덱스해야 할 수도 있습니다. 종종 느린 쿼리 속도는 바로 이곳에서 인덱스의 부족으로 내려 온다.

    테이블에있는 데이터의 양에 따라에 가입되고있는 컬럼에 위치 인덱스해야 할 수도 있습니다. 종종 느린 쿼리 속도는 바로 이곳에서 인덱스의 부족으로 내려 온다.

    또한:

    당신이 내부 조인과 함께 무엇을 찾고 있는지 달성 할 수 - LEFT (이 정확히 무슨 일을하는지에 따라 달라집니다하지만) 내부 조인보다 느린 조인?

  3. ==============================

    3.쿼리의 설명 계획을 게시 할 수 있다면 조금 도움이 될 것이다.

    쿼리의 설명 계획을 게시 할 수 있다면 조금 도움이 될 것이다.

    그러나, 무엇보다도 먼저, 당신은 조인에서 사용되는 모든 필드에 인덱스가? INDEX는 T2 (t2_id, t2_name)에 ix_t2_id CREATE 같은;

    조인 대신 당신이 뭔가를 할 수

    SELECT t1_id, 
        (select t2_name from t2 where t1_id = t2_id), 
        (select t3_name from t3 where t1_id = t3_id), 
        (select t4_name from t4 where t1_id = t4_id), 
        (select t5_name from t5 where t1_id = t5_id), 
        (select t6_name from t6 where t1_id = t6_id), 
        (select t7_name from t7 where t1_id = t7_id), 
        (select t8_name from t8 where t1_id = t8_id), 
        (select t9_name from t9 where t1_id = t9_id) 
    FROM t1 
    

    조인에서하지만, 좋은 쿼리 계획으로, 그 차이가한다.

  4. ==============================

    4.우리는 얼마나 많은 데이터에 대한 말을하는거야? 그것은 당신이 많은 데이터를 가지고 절은 쿼리 프로세스의 마지막에 실행되고있는 곳으로 당신이 그것을 필터링하기 전에 대량의 데이터에 합류 수 있습니다.

    우리는 얼마나 많은 데이터에 대한 말을하는거야? 그것은 당신이 많은 데이터를 가지고 절은 쿼리 프로세스의 마지막에 실행되고있는 곳으로 당신이 그것을 필터링하기 전에 대량의 데이터에 합류 수 있습니다.

    당신은 데이터의보다 제한된에 참여합니다 조인 다른 모든를 선택 제 1 내부에 T1의 데이터를 제한 할 수있는 경우이 경우는 더 빨리 않도록으로 데이터를 필터링합니다.

    Select <your fields> from
    (
    Select * from t1 where t1_id = t1_value
    ) t1
    
    Inner join t2
    on t1.ID = t2.ID
    ...
    

    그되지 대중 데이터의 경우; 당신의 인덱스가 올바른 다음 검사 서버 유형의 것들입니다 확인; 인덱스 조각; 디스크 큐 등

  5. ==============================

    5.당신이 T1의 모든 행을해야하고, 당신이 기본 키에 가입두면 다른 테이블의 쿼리의 속도를 개선 할 수있는 방법은 없습니다 (I는 또한 클러스터 된 인덱스 같아요).

    당신이 T1의 모든 행을해야하고, 당신이 기본 키에 가입두면 다른 테이블의 쿼리의 속도를 개선 할 수있는 방법은 없습니다 (I는 또한 클러스터 된 인덱스 같아요).

    성능을 향상시키기 위해 당신은 결과 집합을 줄이거 나 더러운 트릭을 수행하거나 필요 (예 : 데이터의 비정규 복사본을 만듭니다).

  6. ==============================

    6.쿼리 계획에서 나는 테이블의 같은 언급한다는 결론을 내릴 수, n은 q는 그들이에 합류되고있는 필드에 인덱스가 없습니다.

    쿼리 계획에서 나는 테이블의 같은 언급한다는 결론을 내릴 수, n은 q는 그들이에 합류되고있는 필드에 인덱스가 없습니다.

    이 테이블의 행이 많이 있기 때문에과의 중첩 루프를 사용하고 가입 할 수있는 MySQL을의 유일한 방법 (400000 자신의 직교 제품의 행에 대해), 정말 영원히 소요됩니다.

    이 테이블에 인덱스를 만들거나 PRIMARY KEY로 조인 된 필드를 정의합니다.

  7. ==============================

    7.내가 볼 수 있듯이, T1 테이블 대신 많은 참여와 단일 쿼리에 그들을 가하고, 당신은 아마도이 같은 다른 쿼리의 무언가의 조합을 시도 할 수 있습니다, 모든 테이블과 결합되고있는 것입니다.

    내가 볼 수 있듯이, T1 테이블 대신 많은 참여와 단일 쿼리에 그들을 가하고, 당신은 아마도이 같은 다른 쿼리의 무언가의 조합을 시도 할 수 있습니다, 모든 테이블과 결합되고있는 것입니다.

    SELECT  t1_id, t2_name 
    FROM    t1 LEFT JOIN t2 ON (t1_id = t2_id)
    union 
    SELECT  t1_id, t3_name 
    FROM    t1 LEFT JOIN t3 ON (t1_id = t3_id)
    

    그러나, 경우에 당신이 얻을 것이다 결과는 8 열 그러나 단지 1 열이 없습니다. 즉 당신과 함께 옵션으로 사용할 수 있는지 확실하지 않습니다.

    당신은 어떤 솔루션이 구현해야 한 가지 더있다 - 모든 테이블에 적절한 인덱스를 만들 수 있습니다. 인덱스 컬럼의 가장 좋은 방법은 가장 자주 사용되는 열 조인 또는 WHERE 절에를 만드는 것입니다.

  8. ==============================

    8.단순히 저장 프로 시저에 검색어를 넣고, SQL 서버의 버전에 따라 큰 차이를 만들 수 있습니다. 먼저 다른 최적화를 시도 후이보십시오. (예, 캐시 된 실행 계획 및 기타 내부 서버 최적화가 알고 있지만, 내 실제 현실 세계의 경험, 저장 프로 시저가 빠르게 실행할 수 있습니다.)

    단순히 저장 프로 시저에 검색어를 넣고, SQL 서버의 버전에 따라 큰 차이를 만들 수 있습니다. 먼저 다른 최적화를 시도 후이보십시오. (예, 캐시 된 실행 계획 및 기타 내부 서버 최적화가 알고 있지만, 내 실제 현실 세계의 경험, 저장 프로 시저가 빠르게 실행할 수 있습니다.)

  9. from https://stackoverflow.com/questions/806015/sql-query-joins-multiple-tables-too-slow-8-tables by cc-by-sa and MIT license