2013-06-25 2 views
0

약 100000 개의 항목 (크기 : 2319.58MB, 평균 : 24KB 사전 행)이있는 MySQL 테이블에서 다소 단순한 쿼리를 실행하려고합니다. 간단한 쿼리를 사용한 MySQL 성능 문제

쿼리입니다 :

SELECT 
    n0_.id AS id0, 
    n0_.sentTime AS sentTime1, 
    n0_.deliveredTime AS deliveredTime2, 
    n0_.queuedTime AS queuedTime3, 
    n0_.message AS message4, 
    n0_.failReason AS failReason5, 
    n0_.targetNumber AS targetNumber6, 
    n0_.sid AS sid7, 
    n0_.targetNumber AS targetNumber8, 
    n0_.sid AS sid9, 
    n0_.subject AS subject10, 
    n0_.targetAddress AS targetAddress11, 
    n0_.priority AS priority12, 
    n0_.targetUrl AS targetUrl13, 
    n0_.discr AS discr14, 
    n0_.notification_state_id AS notification_state_id15, 
    n0_.user_id AS user_id16 
FROM 
    notifications n0_ 
    INNER JOIN notification_states n1_ ON n0_.notification_state_id = n1_.id 
WHERE 
    n0_.discr IN (
    'twilioCallNotification', 'twilioSMSNotification', 
    'emailNotification', 'httpNotification' 
) 
ORDER BY 
    n0_.id desc 
LIMIT 
    25 OFFSET 0 

100 1/200 초로 사이의 쿼리.

이것은 테이블의 문을 만드는 것입니다 :

CREATE TABLE notifications (
    id INT AUTO_INCREMENT NOT NULL, 
    notification_state_id INT DEFAULT NULL, 
    user_id INT DEFAULT NULL, 
    sentTime DATETIME DEFAULT NULL, 
    deliveredTime DATETIME DEFAULT NULL, 
    queuedTime DATETIME NOT NULL, 
    message LONGTEXT NOT NULL, 
    failReason LONGTEXT DEFAULT NULL, 
    discr VARCHAR(255) NOT NULL, 
    targetNumber VARCHAR(1024) DEFAULT NULL, 
    sid VARCHAR(34) DEFAULT NULL, 
    subject VARCHAR(1024) DEFAULT NULL, 
    targetAddress VARCHAR(1024) DEFAULT NULL, 
    priority INT DEFAULT NULL, 
    targetUrl VARCHAR(1024) DEFAULT NULL, 
    INDEX IDX_6000B0D350C80464 (notification_state_id), 
    INDEX IDX_6000B0D3A76ED395 (user_id), 
    PRIMARY KEY (id) 
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB; 

ALTER TABLE notifications ADD CONSTRAINT FK_6000B0D350C80464 FOREIGN KEY (notification_state_id) REFERENCES notification_states (id) ON DELETE CASCADE; 
ALTER TABLE notifications ADD CONSTRAINT FK_6000B0D3A76ED395 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE; 

이 쿼리는 Doctrine2 (ORM)에 의해 만들어집니다. 데비안 6.0.7을 실행하는 가상 머신 (1GB 램, 싱글 코어)에서 MySQL 5.5.31을 사용하고 있습니다. 쿼리의 성능이 그렇게 나쁜 이유는 무엇입니까? 데이터베이스 설계 오류입니까 아니면이 양의 데이터를 처리 할 수있는 작은 상자일까요?

답변

2

는 discr 컬럼에 인덱스를 추가

ALTER TABLE `notifications` ADD INDEX `idx_discr` (`discr` ASC) ; 
+0

좋은 점을! ** discr ** 열에 색인을 추가했습니다. 'CREATE INDEX discr_idx ON 알림 (discr)'. 쿼리 실행 시간이 0.1 - 0.5 초가 아니다 – Frido

+0

쿼리에 절을 추가 할 때마다 테이블이 큰 테이블 (작은 차트라도)이라면이 열을 인덱싱하는 것을 잊지 마십시오. 그렇지 않으면 MySQL은 많은 RAM을 소비합니다. 시각. 그러나 데이터베이스 스키마의 경우 "discr_id"및 "discr_label"열과 함께 "discr"속성에 대한 참조 테이블을 만든 다음 "알림"테이블에 외래 키 (discr_id)를 추가하는 것이 좋습니다. 인덱스가 정수가 아니고 문자가 아니기 때문에 성능이 많이 향상됩니다. – kmas

1

notifications.discr로 필터링하고 있지만 색인이없는 것으로 보입니다. 인덱스를 추가하려고 시도 했습니까?