저는 DB 전문가가 아니므로 가능한 한 많이 읽었으며 커뮤니티 응답 덕분에 쿼리 및 쿼리를 여러 번 변경할 수있었습니다. 테이블 구조. 물건을 많이 읽은 후에도 나는 붙어있어 첫 질문을하게되었습니다.큰 쿼리 및 테이블 구조를 최적화하는 데 문제가 있습니다.
나는 사용자가 자신의 이야기를 게시하는 웹 사이트를 운영하고 있습니다. 각 이야기에는 장르, 경고, 다수 저자, 할당 된 복수 문자 등이있을 수 있습니다.
우리는 MySQL 5.x를 실행 중이며 테이블은 PHP로 작성된 InnoDB 웹 사이트입니다. GROUP_CONCAT을 사용하여 결과에 대한 스토리별로 단일 행을 반환합니다. GROUP BY 이야기 ID를 사용하여 이전에 시도했지만 모든 검색어가 완료되기까지 약 16 초가 걸리고 매우 느립니다. 이 새로운 것으로, 그들은 0.175를 취합니다. 그러나 예를 들어, WHERE의 장르가 존재하지 않는다면, 질의는 23 초가 걸립니다! 테스트를 위해 모든 테이블에는 1 백만 개의 레코드가 있고 저자 테이블에는 150 만 개의 테이블이 있습니다. 나는 하나의 MySQL이 사용할 인덱스를 찾기 위해 여분의 인덱스를 배치하려고 시도했다.
일대 다 관계로 정규화 된 것을 얻으려고했습니다. 해결책은 아마 전체 문제를 다루기 때문에 여기서는 약간의 테이블 만 제시 할 것입니다. 어떤 도움을 주셔서 감사합니다, 시간 내 주셔서 감사합니다!
테이블
CREATE TABLE `fanfiction_authors` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`penname` varchar(100) NOT NULL,
`penname_url` varchar(100) NOT NULL,
PRIMARY KEY (`uid`),
KEY `penname_url` (`penname_url`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1000000 ;
-- --------------------------------------------------------
CREATE TABLE `fanfiction_stories` (
`sid` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(200) NOT NULL,
`sinopse` text NOT NULL,
PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1000000 ;
-- --------------------------------------------------------
CREATE TABLE `fanfiction_stories_authors` (
`sid` int(11) NOT NULL,
`uid` int(11) NOT NULL,
KEY `sid_uid` (`sid`,`uid`),
KEY `sid` (`sid`),
KEY `uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
CREATE TABLE `fanfiction_stories_genres` (
`key_id` int(11) NOT NULL AUTO_INCREMENT,
`sid` int(11) NOT NULL,
`genre_id` int(11) NOT NULL,
PRIMARY KEY (`key_id`),
KEY `sid` (`sid`),
KEY `genre_id` (`genre_id`),
KEY `sid_genreid` (`sid`,`genre_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1000000 ;
-- --------------------------------------------------------
CREATE TABLE `fanfiction_stories_stats` (
`sid` int(11) NOT NULL,
`reviews` int(11) NOT NULL,
`recomendacoes` int(11) NOT NULL,
PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
CREATE TABLE `fanfiction_stories_warnings` (
`key_id` int(11) NOT NULL AUTO_INCREMENT,
`sid` int(11) NOT NULL,
`warning_id` int(11) NOT NULL,
PRIMARY KEY (`key_id`),
KEY `sid` (`sid`),
KEY `warning_id` (`warning_id`),
KEY `warningid_sid` (`sid`,`warning_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1000000 ;
----
쿼리
SELECT
st.sid, st.title, st.sinopse,
(SELECT GROUP_CONCAT(CAST(genre_id AS CHAR)) FROM fanfiction_stories_genres WHERE sid = st.sid) as genres,
stats.reviews, stats.recomendacoes,
(SELECT GROUP_CONCAT(CAST(warning_id AS CHAR)) FROM fanfiction_stories_warnings WHERE sid = st.sid) as warnings_ids
FROM
fanfiction_stories AS st
LEFT JOIN fanfiction_stories_stats AS stats ON st.sid = stats.sid
WHERE
st.sid IN (SELECT sid FROM fanfiction_stories_warnings WHERE warning_id = 5) AND
st.sid IN (SELECT sid FROM fanfiction_stories_genres WHERE genre_id = 300)
ORDER BY
st.sid ASC
LIMIT 20
내가 여기 읽을 수 설명 할 수없는, 그래서 드롭 박스에 PRINTSCREEN을 업로드했습니다. 내가 멍청이이기 때문에 이미지를 삽입 할 수 없습니다. 죄송합니다.
유효한 장르가있는 경우 설명입니다 (장르가 300 인 이야기를 찾을 수 있습니다).
http://dl.dropbox.com/u/14508898/Printscreen/stackoverflow_explain_print_001.PNG
http://dl.dropbox.com/u/14508898/Printscreen/stackoverflow_explain_print_002.PNG
미리 감사드립니다.
입력 해 주셔서 감사합니다. Galz! 나는 그것을 시도한 결과가 비어있는 경우 속도가 빨라지지만 (0.007), 결과가 나오면 20 초가 걸린다. 설명 : filesort를 사용하여 임시 사용. 나는 GROUP BY –
에 의한 것 같아요. @Michael - 같은 GROUP BY를 버리고 동일한 결과를 얻는다고 생각합니다. fanfiction_stories_warnings에 하나의 레코드가 있고 동일한 sid 및 warning_id를 갖고 있고 fanfiction_stories_genres에 하나의 레코드 만 있으면 동일한 시드 및 genre_id와 함께 ... – Galz
예, GROUP BY가없는 벤치마킹 이었지만 완벽합니다. 결과는 평균 0.08이며 표시 할 결과가없는 경우 평균 0.002입니다. 고마워요, 갈쯔! 너 정말로 나를 구했어. :) –