[SQL] 시간을 줄이기 위해 선택 MySQL을 다시 쓰기 디스크에 TMP를 작성
SQL시간을 줄이기 위해 선택 MySQL을 다시 쓰기 디스크에 TMP를 작성
나는 웹 페이지를 작성하는 데 사용으로 매우 좋지 않아 몇 분을 복용 MySQL의 쿼리가 있습니다.
세 개의 테이블이 사용됩니다 poster_data 개별 포스터에 대한 정보가 포함되어 있습니다. poster_categories리스트 모든 종류 (영화, 예술, 등) 동안 posterid 번호가 들어있을 수있는 카테고리 poster_prodcat 목록 하나 개의 포스터는 말, 영화, 인디아나 존스, 해리슨 포드, 모험 영화, 등 여러 줄 것이다
이 느린 쿼리입니다 :
select *
from poster_prodcat,
poster_data,
poster_categories
where poster_data.apnumber = poster_prodcat.apnumber
and poster_categories.apcatnum = poster_prodcat.apcatnum
and poster_prodcat.apcatnum='623'
ORDER BY aptitle ASC
LIMIT 0, 32
에 따르면 설명 :
그것은 몇 분을 복용했다. poster_prodcat이 조금 넘는 1700 만있는 동안 Poster_data는 겨우 80 개 행이 있습니다. poster_prodcat.apcatnum이 = '623'을 40 만에 대한 결과를 가지고하는 동안이와 다른 종류의 쿼리는 거의 눈에 띄지, 디스크에 기록되어있다 선택
해결법
-
==============================
1.당신이 도움이되기를 바랍니다 - http://pastie.org/1105206
당신이 도움이되기를 바랍니다 - http://pastie.org/1105206
drop table if exists poster; create table poster ( poster_id int unsigned not null auto_increment primary key, name varchar(255) not null unique ) engine = innodb; drop table if exists category; create table category ( cat_id mediumint unsigned not null auto_increment primary key, name varchar(255) not null unique ) engine = innodb; drop table if exists poster_category; create table poster_category ( cat_id mediumint unsigned not null, poster_id int unsigned not null, primary key (cat_id, poster_id) -- note the clustered composite index !! ) engine = innodb; -- FYI http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html select count(*) from category count(*) ======== 500,000 select count(*) from poster count(*) ======== 1,000,000 select count(*) from poster_category count(*) ======== 125,675,688 select count(*) from poster_category where cat_id = 623 count(*) ======== 342,820 explain select p.*, c.* from poster_category pc inner join category c on pc.cat_id = c.cat_id inner join poster p on pc.poster_id = p.poster_id where pc.cat_id = 623 order by p.name limit 32; id select_type table type possible_keys key key_len ref rows == =========== ===== ==== ============= === ======= === ==== 1 SIMPLE c const PRIMARY PRIMARY 3 const 1 1 SIMPLE p index PRIMARY name 257 null 32 1 SIMPLE pc eq_ref PRIMARY PRIMARY 7 const,foo_db.p.poster_id 1 select p.*, c.* from poster_category pc inner join category c on pc.cat_id = c.cat_id inner join poster p on pc.poster_id = p.poster_id where pc.cat_id = 623 order by p.name limit 32; Statement:21/08/2010 0:00:00.021: Query OK
-
==============================
2.나열된 쿼리는 최종 쿼리가 모양을 어떻게? (그들은 apcatnum = / ID를 가지고 그래서 /?)
나열된 쿼리는 최종 쿼리가 모양을 어떻게? (그들은 apcatnum = / ID를 가지고 그래서 /?)
여기서 poster_data.apnumber = poster_prodcat.apnumber 및 poster_categories.apcatnum = poster_prodcat.apcatnum 및 poster_prodcat.apcatnum = '623'
poster_prodcat.apcatnum = '623' 크게 데이터 세트 MySQL이에 일해야 감소, 따라서이 쿼리의 첫 번째 구문 분석 된 부분이되어야한다.
그런 곳-비교를 교환하기 위하여 계속 데이터 세트 가장 먼저 구문 분석됩니다 최소화하는 그래서.
또한 하위 쿼리를 시도 할 수 있습니다. 나는 의지 도움말하지만, MySQL은 아마 처음 3 개 테이블을받지 않습니다 만, 먼저 서브 쿼리하고 다른 하나를 모르겠어요. 조회하면서 메모리 소모를 최소화한다. 당신이 정말로 모든 열을 선택하려면 (당신은 *이 사용하고있는대로)이 옵션을 선택하지 않습니다 만.
-
==============================
3.당신은 POSTER_DATA에서 apnumber에 인덱스가 있어야합니다. 841152 개 기록을 검사하면 성능을 죽이는 것입니다.
당신은 POSTER_DATA에서 apnumber에 인덱스가 있어야합니다. 841152 개 기록을 검사하면 성능을 죽이는 것입니다.
-
==============================
4.쿼리처럼 보인다는 순서를 얻기 위해 apptitle 인덱스를 사용하고 있지만, 결과를 필터링하는 전체 검사를하고있다. 난 당신이 poster_data에 모두 apptitle 및 apnumber에서 복합 인덱스가 있다면 도움이 될 것 같아요. MySQL은 다음 정렬 순서 및 필터 두 가지를 모두 수행하려면이 옵션을 사용할 수 있습니다.
쿼리처럼 보인다는 순서를 얻기 위해 apptitle 인덱스를 사용하고 있지만, 결과를 필터링하는 전체 검사를하고있다. 난 당신이 poster_data에 모두 apptitle 및 apnumber에서 복합 인덱스가 있다면 도움이 될 것 같아요. MySQL은 다음 정렬 순서 및 필터 두 가지를 모두 수행하려면이 옵션을 사용할 수 있습니다.
create index data_title_anum_idx on poster_data(aptitle,apnumber);
from https://stackoverflow.com/questions/3534597/rewriting-mysql-select-to-reduce-time-and-writing-tmp-to-disk by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SQL 서버 쿼리는 데이터 유형, NOT NULL 및 PRIMARY KEY 제약 조건과 함께 테이블에 열 목록을 얻을 수 있습니다 (0) | 2020.04.08 |
---|---|
[SQL] 쿼리 SQL Server가 그룹의 마지막 행을 찾기 (0) | 2020.04.08 |
[SQL] mysql_num_rows도 () : 제공된 인수가 유효한 MySQL의 결과 리소스 아니다 [중복] (0) | 2020.04.08 |
[SQL] SQL Server의 N 행을 선택 (0) | 2020.04.08 |
[SQL] 어떻게 다양한 형식 SQLite는의 피벗 또는 즉 선택에 표는 긴 형식으로 저장? (0) | 2020.04.08 |