FORCE INDEX (abc)
키워드를 사용하여 MySQL이 쿼리를 실행하는 방식을 변경할 수 있음을 알고 있습니다. 그러나 실행 명령을 변경하는 방법이 있습니까?MySQL 실행 순서를 강제하는 방법이 있습니까?
내 쿼리는 다음과 같습니다
SELECT c.*
FROM table1 a
INNER JOIN table2 b ON a.id = b.table1_id
INNER JOIN table3 c ON b.itemid = c.itemid
WHERE a.itemtype = 1
AND a.busy = 1
AND b.something = 0
AND b.acolumn = 2
AND c.itemid = 123456
내가 사용하는 모든 관계/제약의 키가 있습니다. 내가이 문장에 대해 설명을하면, mysql이 먼저 쿼리를 시작한다는 것을 알 수있다.
id select_type table type
1 SIMPLE c ref
2 SIMPLE b ref
3 SIMPLE a eq_ref
는 그러나, 나는 a -> b -> c
빠른 것 순서로 쿼리 특정 순서를 사용하는 mysql을 말할 수있는 방법이 있나요 (I는 것을 증명) 알아?
업데이트 : 이것이 내가 a -> b -> c
이 더 빠르다는 것을 알고있는 방법입니다.
위 쿼리는 완료하는 데 1.9 초가 걸리고 7 행을 반환합니다. 내가
SELECT c.*
FROM table1 a
INNER JOIN table2 b ON a.id = b.table1_id
INNER JOIN table3 c ON b.itemid = c.itemid
WHERE a.itemtype = 1
AND a.busy = 1
AND b.something = 0
AND b.acolumn = 2
HAVING c.itemid = 123456
쿼리가 0.01 초에 완료에 쿼리를 변경하는 경우 (가진 사용하지 않고 나는 10.000 행을 얻을). 그러나이 쿼리는 단순화 된 예제이기 때문에 이는 훌륭한 해결책이 아닙니다. 현실 세계에서 나는 c에서 다른 테이블에 조인했습니다. HAVING
은 전체 결과에 대해 실행되는 필터이므로 db에서 nescessary보다 많은 magnitues 레코드를 가져옵니다.
Edit2가 : 그냥 몇 가지 정보 :이 쿼리에
- 변수 부분은 c.itemid이다. 다른 모든 것은 변경되지 않는 고정 값입니다.
- 인덱스 설정 미세하고 MySQL은 1가 나를 위해 A와 B 사이
- 를 오른쪽 것들을 선택 : N의 관계 (인덱스 PRIMARY 사용한다) (B) 사이
- 및 C 많은 많은 존재 관계
점은 MySQL의 테이블 A를 조회 시작하고이 길 아래로 C 및 원형이 아닌 다른 방법 일을해야한다는 것입니다 (인덱스 IDX_ITEMID이 사용됩니다). 그 변화가 생기면
솔루션 : 내가 원하지만이 작동하는 것 같다 아니 정확히 :
SELECT c.*
FROM table1 a
INNER JOIN table2 b ON a.id = b.table1_id
INNER JOIN table3 c ON b.itemid = c.itemid
WHERE a.itemtype = 1
AND a.busy = 1
AND b.something = 0
AND b.acolumn = 2
AND c.itemid = 123456
AND f.id IN (
SELECT DISTINCT table2.id FROM table1
INNER JOIN table2 ON table1.id = table2.table1_id
WHERE table1.itemtype = 1 AND table1.busy = 1)
'a -> b -> c'가 더 빠를 것이라고 어떻게 증명 했습니까? 또한 색인을 보여줄 수 있습니까? – Unreason
테스트가 빠르면 실제로 많은 양의 데이터가 미리로드되고 정상적인로드를 시뮬레이트하지 않고 테스트하기가 어려울 수 있습니다. MySQL이 자체 최적화를 수행하는 것이 좋으며, 더 많은 데이터를 얻는 것은 점점 더 정확 해지고 (시간이 지남에 따라 또는 ANALYZE TABLE을 한두 번 실행 함) 문제에 부딪혔을 때만 인덱스를 강제 실행합니다. 그런 문제는 존재한다. 나는 분명히 MySQL의 쿼리 계획이 pathalogically 나쁘지만 특정 인덱스를 강요하고 따라서 주문을 결합한 후 좋고 효율적으로 작동했습니다. – thomasrutter
@thomasrutter : MySQL의 최적화 결과가 2-7 초 (로드/데이터 양에 따라 다름) 쿼리에서 내 최적화를 사용하는 것보다 다른 선택이 없다면 : Hammerite가 제안했습니다. STRAIGHT_JOIN은 내가 원하는 것을 수행하고 1은 쿼리를 고정 시켰습니다 천 번. –