2013-10-17 2 views
1

이 트리거가 있습니다. 들어오는 로그가 입력 필터와 일치하면 데이터베이스에 저장되지 않습니다. 그러나 각 Primitive_filter의 "히트 수"를 유지하려고합니다. hit_rate라는 이름의 열이 있습니다.이 열은 int (30)입니다. 어떻게 할 수있는 방법이 있습니까? 어쩌면 특정 오류일까요? 아니면 sth? Thx 도움.데이터베이스에서 선택하고 열을 업데이트하는 mysql 트리거

UPDATE Primitive_filters SET hit_rate = hit_rate + 1 where Primitive_filters.id = ???; 

트리거는

delimiter // 
CREATE TRIGGER inputFilter 
before insert 
on Logs 
for each row 
begin 
declare msg varchar(255); 
IF (SELECT COUNT(*) FROM Primitive_filters, Primitive_in_filter, Filters WHERE 
Filters.name = "input" AND Filters.id = Primitive_in_filter.id_filter AND Primitive_in_filter.id_primitive = Primitive_filters.id AND 
(Primitive_filters.id_host LIKE CONCAT('%',(SELECT host FROM Hosts WHERE id = new.id_host),'%') OR Primitive_filters.id_host IS NULL) AND 
(Primitive_filters.facility LIKE CONCAT('%',new.facility,'%') OR Primitive_filters.facility IS NULL) AND 
(Primitive_filters.priority LIKE CONCAT('%',new.priority,'%') OR Primitive_filters.priority IS NULL) AND 
(Primitive_filters.program LIKE CONCAT('%',new.program,'%') OR Primitive_filters.program IS NULL) AND 
(new.msg REGEXP Primitive_filters.msg OR Primitive_filters.msg IS NULL)) > 0 THEN CALL raise_error; END IF; 
END // 

delimiter ; 

답변

0

이 질문에 대한 답이 아닙니다.

코드에서 잠재적으로 심각한 성능 문제를 해결하는 방법에 대한 힌트 일뿐입니다.

이를 사용하지 마십시오

IF (SELECT COUNT(*) FROM ... giant query ...) > 0 
THEN CALL raise_error; 
END IF; 

사용이 대신 :

IF EXISTS (SELECT 1 FROM ... giant query ...) 
THEN CALL raise_error; 
END IF; 

이전 조건은 수를 계산 ... 그것은 쿼리에서 반환 된 모든 행을 읽어야합니다
하는 경우 질의는 10 억 개의 행을 반환하지만 사용자가 give me a count of rows을 요청했기 때문에 쿼리를 모두 읽어야합니다.
그런 다음 쿼리가 카운트를 반환 한 후 검사가 수행됩니다. 쿼리가 적어도 한 행을 반환하면 작업을 수행하십시오.



후자의 조건은 쿼리가 첫 번째 행을 반환 할 때 쿼리 실행이 중지되어 시간과 리소스를 절약합니다.

관련 문제