“tmp 테이블에 복사”가 매우 느림


15

이것은 내 쿼리 예입니다.

SELECT
    nickname, 
    CASE class_id
      WHEN 1 THEN 'Druid'
      WHEN 2 THEN 'Necromancer'
      WHEN 3 THEN 'Mage'
      WHEN 4 THEN 'Priest'
      WHEN 5 THEN 'Warrior'
      WHEN 6 THEN 'Stalker'
      WHEN 7 THEN 'Paladin'
      WHEN 8 THEN 'Psionic'
    END class_name,
    ROUND(AVG(level),2) level,
    ROUND(AVG(tabard_id),2) tabard,
    CASE rank_id
      WHEN 1 THEN 'Leader'
      WHEN 2 THEN 'Officer'
      WHEN 3 THEN 'Veteran'
      WHEN 4 THEN 'HonoryMember'
      WHEN 5 THEN 'OrdinaryMember'
      WHEN 6 THEN 'Alt'
      WHEN 7 THEN 'Apprentice'
      WHEN 8 THEN 'Penalty'
    END rank_name,
    ROUND(AVG(loyality),2) loyality,
    ROUND((MAX(authority)-MIN(authority))/AVG(tabard_id)) authority_effective,
    MAX(authority)-MIN(authority) authority_delta,
    MIN(authority) authority_begin,
    MAX(authority) authority_end
FROM users
    LEFT JOIN level_history ON level_history.users_id = users.id
    LEFT JOIN tabard_history ON tabard_history.users_id = users.id
    LEFT JOIN rank_history ON rank_history.users_id = users.id
    LEFT JOIN loyality_history ON loyality_history.users_id = users.id
    LEFT JOIN authority_history ON authority_history.users_id = users.id
    LEFT JOIN guilds_has_users ON guilds_has_users.users_id = users.id
    LEFT JOIN report ON report.id = authority_history.report_id
      AND report.id = level_history.report_id
      AND report.id = loyality_history.report_id
      AND report.id = rank_history.report_id
      AND report.id = tabard_history.report_id
WHERE report.date BETWEEN '2011-10-24 00:00:00' AND '2011-10-30 23:59:59'
  AND guilds_has_users.active = 1
GROUP BY users.id;

그 선택에 대해 설명하십시오 :

id  select_type   table               type    possible_keys                                            key                          key_len   ref                                           rows    Extra
1   SIMPLE        guilds_has_users    ref     fk_guilds_has_users_users1,active_IDX                    active_IDX                   1         const                                         139     Using where; Using temporary; Using filesort
1   SIMPLE        users               eq_ref  PRIMARY                                                  PRIMARY                      4         z92985_orlandino.guilds_has_users.users_id    1    
1   SIMPLE        level_history       ref     fk_level_history_users1,fk_level_history_report1,u...    fk_level_history_users1      4         z92985_orlandino.guilds_has_users.users_id    1       Using where
1   SIMPLE        report              eq_ref  PRIMARY,date_IDX,id_date_IDX                             PRIMARY                      4         z92985_orlandino.level_history.report_id      1       Using where
1   SIMPLE        tabard_history      ref     fk_tabard_history_users1,fk_tabard_history_report1...    fk_tabard_history_users1     4         z92985_orlandino.level_history.users_id       1       Using where
1   SIMPLE        rank_history        ref     fk_rank_history_users1,fk_rank_history_report1,use...    fk_rank_history_users1       4         z92985_orlandino.users.id                     1       Using where
1   SIMPLE        loyality_history    ref     fk_loyality_history_users1,fk_loyality_history_rep...    fk_loyality_history_users1   4         z92985_orlandino.rank_history.users_id        1       Using where
1   SIMPLE        authority_history   ref     fk_authority_history_users1,fk_authority_history_r...    fk_authority_history_users1  4         z92985_orlandino.level_history.users_id       1       Using where

해당 선택의 프로파일 링은 다음을 알려줍니다.

(139 total, Query took 4.4918 sec)
Copying to tmp table 4.488318

MySQL 변수에 대한 정보는 다음과 같습니다.

SHOW VARIABLES LIKE '%buffer%';

Variable_name              Value
bulk_insert_buffer_size    8388608
join_buffer_size           131072
key_buffer_size            12884901888
myisam_sort_buffer_size    8388608
net_buffer_length          16384
preload_buffer_size        32768
read_buffer_size           131072
read_rnd_buffer_size       25165824
sort_buffer_size           2097144
sql_buffer_result          OFF

tmp 테이블로 복사하는 것이 왜 그렇게 느린가요? 쿼리 속도를 향상시키는 방법은 무엇입니까?

추신 : 호스팅 제공 업체가 허용하지 않기 때문에 MySQL을 구성 할 수 없습니다.

답변:


22

세션 내에서 특정 변수를 설정해야 할 수도 있습니다

이러한 특정 값은 DB 연결이 쿼리를 효율적으로 수행하기에 너무 작을 수 있습니다. 다음과 같이 설정할 수 있습니다.

  • 이 설정이 현재 다음을 수행하는 값을 확인하려면
    • SHOW VARIABLES LIKE 'max_heap_table_size';
    • SHOW VARIABLES LIKE 'tmp_table_size';
  • max_heap_table_size를 64M으로 설정하려면 다음을 수행하십시오.
    • SET max_heap_table_size = 1024 * 1024 * 64;
  • tmp_table_size를 32M으로 설정하려면 다음을 수행하십시오.
    • SET tmp_table_size = 1024 * 1024 * 32;

임시 테이블 사용법에 대한 MySQL 설명서를 참조하십시오

자체 세션 내에서이 값을 설정할 수없는 경우 호스팅 제공 업체에 문의하여 my.cnf에서 동적으로 설정하십시오.

시도 해봐 !!!


세션 내에서 변수를 설정하면 +1,이 쿼리가 도움이 될 수 있습니다. 다소 복잡해 보입니다.
Dave Rix

5

출력을 생성하는 데 꼭 필요한 테이블로만 쿼리를 줄이거 나 정보의 다른 부분을 가져 오기 위해 쿼리를 여러 개의 개별 쿼리로 분할 할 수 있습니까?

데이터에 대해 세 개의 개별 쿼리를 실행하는 것이 하나의 거대한 쿼리를 실행하는 것보다 빠릅니다 (특히 데이터베이스가 수십만 행으로 커지기 시작하는 경우).

나는 또한 내 자신의 일에서 LEFT JOIN 쿼리가 반드시 가장 효율적인 것은 아니라는 으므로 절대적으로 필요할 때만 사용하십시오 ...

희망이 있습니다 :)


1
때로는 더 작은 쿼리가 대량의 테이블과 왼쪽 조인보다 더 의미가 있습니다 (예 : stackoverflow.com/questions/5983156/… ) +1 !!!
RolandoMySQLDBA
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.