2013-10-05 4 views
2

에 의해 삭제 :MySQL의 파티셔닝은 고려 : 다음 표를 ID로 선택할 수 있지만 날짜

CREATE TABLE `event` (
    `uid` bigint(13) NOT NULL, 
    `time` bigint(14) NOT NULL, 
    `type` smallint(5) NOT NULL, 
    `msg` varchar(2048) DEFAULT NULL, 
    KEY `uid` (`uid`), 
    KEY `time` (`time`), 
    KEY `time_type_uid` (`time`,`type`,`uid`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

기본적으로 내가 무엇을 :

    이 이 INSERT는, 현재의 크기는 약 100 하루에 1 백만 행입니다 ~
  • 만 개 항목
  • DELETE 모든 행보다 오래된 백일 :
    • 문 # 1 : DELETE FROM event WHERE time < unix_timestamp() - 100 * 86400;
    • 진술 # 2 : DELETE FROM event WHERE time < unix_timestamp() - 100 * 86400 LIMIT 1000;
  • 사용자 것이다 SELECT UID 모든 이벤트가 약 500 그렇게하지가 아주 많이, 합계에서 하루 조회 :
    • 문 # 1 = 4711 AND type IN (23,1002,12 SELECT * FROM event WHERE uid, 1);
    • 문 # 2 = 4711 SELECT * FROM event WHERE uidtype AND IN (23,1002,12,1) AND AND 1381051061 1381051861 BETWEEN time; 이 테이블을 취급

특히 테이블에 DELETE 작업 블록 INSERT S/SELECT들 때문에, 매우 느린되었다. 우리는 일일 벌크를 위에서 설명한대로 (문 # 1) 시도했는데 더 이상 테이블을 차단하지 않고는 작동하지 않습니다. 현재 30 초 (명세서 # 2)마다 삭제 중이지만 10 초 동안 차단됩니다.

우리는 INSERT로드를 늘릴 계획이지만 첫 번째 테스트에서는 "시스템 블록"상태에 매달려있는 스레드가 발생합니다. 이는 I/O 때문인 것으로 생각됩니다. 서버 설정은 mysqltuner.pl에서 제안하는대로 최적화됩니다. 하드웨어 시스템은 확실히 I/O 문제가 있으며 "있는 그대로"입니다. 불행히도 여러 이유로 인해 변경 될 수 없습니다. 우리는 심지어 루트 액세스 권한이 없습니다.

솔루션을 파티셔닝하고 MyISAM을 사용하는 것이 가장 좋습니다. 우리는 하드웨어를 개선하기 전에 가능한 모든 것을 최적화 할 필요가 있습니다.

+0

투표의 여파 : 너무 광범위합니다. 매혹적인 문제이지만 여기에 확실하게 대답하기에는 너무 광범위하고 틀림없이 엄격하게 프로그래밍 문제는 아닙니다. 우리는 파티션하는 방법을 알려줄 수는 있지만 추상적으로는 최적화 할 수 없습니다. 왜 InnoDB가 아닌가? 서버 설정이란 무엇입니까? 시스템 사양 및로드 란 무엇입니까? 실행중인 다른 쿼리는 무엇입니까? 얼마나 자주 삭제합니까? 더 자주 할 수 있습니까? 당신의 쿼리 패턴에 맞는 인덱스가 있습니까? (내 추측은 그렇지 않다.) 기타 – pilcrow

+0

의견을 보내 주셔서 감사합니다. 광범위한 문제에 대한 최적화 도움말을 제공하는 것이 어렵다는 것을 알고 있습니다. 나는 이와 같은 데이터를 다루는 것이 일반적인 문제 일 수 있다고 생각했다. 좀 더 자세한 내용을 추가하여 도움이되기를 바랍니다. –

+0

dba.stackexchange는 어떤 종류의 최적화가 적절한 지 질문하고 그 효과를 측정하는 방법을 묻기에 더 좋은 곳입니다. – pilcrow

답변

0

읽을 수있는 스냅 샷을 얻으려면 InnoDB with snapshot isolation을 사용하면됩니다. 그렇게하면 독자는 큰 삭제 작업에 의해 차단되지 않습니다. 이 표준적인 상황을 위해 파티셔닝을해야한다고 생각하지 않습니다. 파티셔닝은 큰 망치와 침입자입니다. 어쩌면 몇 가지 간단한 방법으로 충분할 것입니다.

0

파티셔닝 (잘 수행되지만 sysadmin 털볼이 될 수 있음)으로 들어가기 전에 몇 가지를 시도해보십시오.

DELETE 정리 작업을 하루에 여러 번 (한 시간에 여러 번) 실행하므로 실행될 때마다 백만 개의 행을 훑어 볼 필요가 없습니다.

는 또 다시

DELETE FROM event 
      WHERE TIME < < unix_timestamp()-100*86400 
     LIMIT 10000 

을 실행 해보십시오. 이렇게하면 DELETE 조작이 테이블을 잠근 시간을 줄이고 다른 조작을 위해 해제 할 수 있습니다.

올바른 합성 색인 (시간, 유형, uid)이 있는지 여부를 확인하십시오. 표시 한 쿼리는 해당 인덱스를 악용하지 않으며 색인을 삽입하는 데 시간이 걸립니다. 단순히 해당 색인을 삭제하려고 할 것 같습니다. 언급 한 쿼리에 대한 인덱스 (uid, type)가 필요할 수 있습니다.

SELECT *의 사용을 제거하십시오. 대신 응용 프로그램에 필요한 열만 검색하십시오. MySQL은 필요한 데이터 항목을 정확히 알고있을 때 놀라운 최적화를 수행 할 수 있습니다.

일일 또는 주간 다운 타임을 감당할 수 있습니까? 그렇다면

OPTIMIZE NO_WRITE_TO_BINLOG TABLE event 

을 한 번씩 사용하여 테이블 및 색인 구조를 정리하십시오.

+0

감사합니다. 이미 한도로 삭제를 시도했습니다. 작동하지만 약 10 초 동안 차단됩니다. 동시에 더 많은 INSERT 작업을하지 않을 것입니다. –