방금 동일한 레이아웃을 가진 여러 테이블로 구성된 로깅 시스템을 설정했습니다.
각 데이터 소스마다 하나의 테이블이 있습니다.
로그 뷰어의 경우
- UNION 모든 로그 테이블 ,
- 계정별로 필터링 ,
- 소스 식별을위한 의사 열 추가
- 시간이별로 정렬 ,
- 및 페이지 매김을 위해 그들을 제한 .
모든 테이블에는 zeitpunkt
색인화 된 날짜 / 시간 열 이라는 필드 가 있습니다.
나의 첫번째 시도는 :
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730)
ORDER BY zeit DESC LIMIT 10;
두 테이블의 모든 행이 서브 쿼리에 의해 리턴되고 UNION
.
내 해결 방법은 다음과 같습니다.
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
ORDER BY zeit DESC LIMIT 10;
쿼리 엔진이 여기에서 인덱스를 사용하기를 기대하고 있었기 때문에 두 하위 쿼리가 모두에 앞서 정렬되고 제한되어야하기 UNION
때문에 행을 병합하고 정렬합니다.
나는 이것이 사실이라고 생각했지만 EXPLAIN
쿼리에서 실행 하면 하위 쿼리가 여전히 두 테이블을 모두 검색한다는 것을 알 수 있습니다.
EXPLAINing
하위 쿼리 자체는 원하는 최적화를 보여 주지만 UNIONing
함께하지는 않습니다.
내가 뭘 놓 쳤니?
하위 쿼리 ORDER BY
내부의 절 UNION
은가 없으면 무시 LIMIT
되지만 한계가 있음을 알고 있습니다.
편집 :
실제로account_id
조건이없는 쿼리도있을 것입니다.
테이블이 이미 존재하며 데이터로 채워져 있습니다. 소스에 따라 레이아웃이 변경 될 수 있으므로 분할하여 유지하고 싶습니다. 또한 로깅 클라이언트는 다른 이유로 다른 자격 증명을 사용합니다.
로그 리더와 실제 테이블 사이에 일종의 계층을 유지해야합니다.
다음은 전체 쿼리와 첫 번째 하위 쿼리 및 테이블 레이아웃에 대한 실행 계획입니다.
UNION DISTINCT
? 추가 식별 열로 인해 서브 쿼리마다 결과가 다르므로 정렬과 구별을 강제 할 필요가 없습니다. 사용하십시오 UNION ALL
.
source
열을 추가하여 모든 로그를 동일한 테이블에 두는 것이 낫지 않습니까? 이렇게하면 UNION
모든 데이터에서을 피하고 색인을 사용할 수 있습니다.
UNION ALL
다른 실행 계획 이 산출 되는지 확인하십시오 .
(account_id, zeitpunkt)
입니다. 그런 색인이 있습니까? 두 번째로 가장 좋은 방법은 싱글이라고 생각(zeitpunkt)
하지만 사용되는 경우 효율성은 행이account_id=730
나타나는 빈도에 따라 다릅니다 .