다음을 통해 쿼리 플래너를 어느 정도 제어할 수 있습니다. 명시적인 사용가입구문. 보려면 이것이 중요한 이유는 먼저 배경 지식이 필요하기 때문입니다.
다음과 같은 간단한 조인 쿼리에서:
SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id;
플래너는 주어진 테이블을 어떤 순서로든 자유롭게 조인할 수 있습니다. 에 대한 예를 들어 다음을 사용하여 A를 B에 조인하는 쿼리 계획을 생성할 수 있습니다.어디조건a.id = b.id, 그런 다음 C를 이 조인에 조인합니다. 테이블, 다른 하나를 사용하여어디조건. 또는 B를 C에 결합한 다음 A를 해당 결과에 결합할 수도 있습니다. 아니면 A를 C에 결합한 다음 B와 결합할 수 있습니다. 하지만 이는 A와 C의 전체 데카르트 곱은 비효율적입니다. 을 형성해야 하며, 해당 조건이 없습니다.어디에서최적화를 허용하는 절 조인. (모든 조인은 다음과 같습니다.PostgreSQL실행자는 두 입력 사이에서 발생합니다. 테이블이므로 하나 이상의 결과를 구축해야 합니다. 이러한 패션 중 하나입니다.) 중요한 점은 이러한 패션이 서로 다른 조인 가능성은 의미상 동일한 결과를 제공합니다. 하지만 실행 비용이 크게 다를 수 있습니다. 그러므로, 롤 토토는 모든 것을 탐색하여 가장 좋은 것을 찾으려고 노력할 것입니다. 효율적인 쿼리 계획.
쿼리가 2~3개의 테이블만 포함하는 경우에는 많은 가입 주문이 걱정됩니다. 그러나 가능한 조인 수는 테이블 수가 늘어남에 따라 주문도 기하급수적으로 늘어납니다. 10개 정도의 입력 테이블을 넘어서는 것은 더 이상 실용적이지 않습니다. 모든 가능성에 대한 철저한 검색, 심지어 6개 이상의 가능성까지 일곱 개의 테이블을 계획하는 데는 짜증스러울 정도로 오랜 시간이 걸릴 수 있습니다. 언제 입력 테이블이 너무 많습니다.PostgreSQL플래너가 다음에서 전환됩니다. a에 대한 철저한 검색유전적제한된 가능성을 통한 확률적 검색입니다. (전환 임계값은 다음에 의해 설정됩니다.geqo_threshold런타임 매개변수.) 유전자 검색에는 시간이 덜 걸리지만 가능한 최선의 계획을 반드시 찾을 수는 없습니다.
쿼리가 외부 조인과 관련된 경우 롤 토토는 더 적은 양의 일반(내부) 조인보다 자유로워집니다. 예를 들어, 고려하십시오:
SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
이 쿼리의 제한사항은 표면적으로 유사하지만 이전 예와는 의미가 다릅니다. 일치하는 행이 없는 A의 각 행에 대해 행을 내보내야 합니다. B와 C의 조인. 따라서 플래너는 조인을 선택할 수 없습니다. 여기에서 주문하세요. B를 C에 결합한 다음 A를 해당 결과에 결합해야 합니다. 따라서 이 쿼리는 이전 쿼리보다 계획하는 데 시간이 덜 걸립니다. 쿼리. 다른 경우에는 기획자가 다음 사항을 결정할 수 있습니다. 둘 이상의 조인 순서가 안전합니다. 예를 들어, 다음과 같습니다:
SELECT * FROM a LEFT JOIN b ON (a.bid = b.id) LEFT JOIN c ON (a.cid = c.id);
먼저 A를 B 또는 C에 결합하는 것이 유효합니다. 현재는 만전체 조인조인을 완전히 제한합니다. 주문. 가장 실제적인 사례는 다음과 같습니다.왼쪽 가입또는오른쪽 조인될 수 있습니다 어느 정도 재배열되었습니다.
명시적 내부 조인 구문(내부 가입, 교차 조인, 또는 장식되지 않은가입)은 의미상으로 동일합니다. 입력 관계 나열발신그러니까 조인 순서를 제한하지 않습니다.
대부분의 종류에도 불구하고가입하지 마세요 조인 순서를 완전히 제한하여 지시할 수 있습니다.PostgreSQL쿼리 롤 토토 모두 치료가입제약적인 조항 어쨌든 가입 순서. 예를 들어 다음 세 가지 쿼리는 다음과 같습니다. 논리적으로 동등함:
SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id; SELECT * FROM a CROSS JOIN b CROSS JOIN c WHERE a.id = b.id AND b.ref = c.id; SELECT * FROM a JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
그러나 우리가 기획자에게 다음을 존중하라고 말한다면가입순서, 두 번째와 세 번째는 시간이 덜 걸립니다 처음보다 계획을 세워라. 이 효과는 걱정할 가치가 없습니다. 테이블은 3개뿐이지만 많은 테이블이 있으면 생명의 은인이 될 수 있습니다. 테이블.
계획자가 다음의 조인 순서를 따르도록 강제합니다. 명시적인가입s, 설정join_collapse_limit런타임 매개변수를 1로 설정합니다. (다른 가능한 값은 논의됨) 아래.)
조인 순서를 완전히 제한할 필요는 없습니다. 사용해도 괜찮으니 검색 시간을 단축하기 위해가입일반 항목 내의 연산자발신목록. 예를 들어 다음을 고려하세요.
SELECT * CROSS JOIN b, c, d, e WHERE ...;
함께join_collapse_limit= 1, 이 플래너는 A를 다른 A와 결합하기 전에 B와 결합하도록 강제합니다. 테이블이지만 선택 사항을 제한하지는 않습니다. 이에 예를 들어, 가능한 조인 주문 수는 다음과 같이 줄어듭니다. 5의 인수.
이러한 방식으로 계획자의 검색을 제한하는 것은 유용합니다. 계획 시간을 단축하고 방향을 잡는 기술 좋은 쿼리 계획을 세우는 플래너입니다. 플래너가 잘못된 조인을 선택한 경우 기본적으로 주문하려면 다음을 통해 더 나은 주문을 선택하도록 강제할 수 있습니다.가입구문 — 당신이 알고 있다고 가정 더 나은 주문, 즉. 실험을 권장합니다.
계획 시간에 영향을 미치는 밀접하게 관련된 문제는 다음과 같습니다. 하위 쿼리를 상위 쿼리로 축소합니다. 예를 들어, 고려하십시오:
선택 *
x, y에서,
    (SELECT * FROM a, b, c WHERE 무언가) AS ss
다른 곳은 어디인가요?
  이 상황은 가입하다; 보기의선택규칙은 다음과 같습니다 뷰 참조 위치에 삽입되어 쿼리가 많이 생성됩니다. 위와 같이. 일반적으로 기획자는 계획을 무너뜨리려고 노력합니다. 상위 항목에 대한 하위 쿼리를 수행하면 다음이 생성됩니다.
SELECT * FROM x, y, a, b, c WHERE 무언가 AND다른 것;
이것은 일반적으로 계획을 세우는 것보다 더 나은 계획을 낳습니다. 하위 쿼리를 별도로 수행하십시오. (예를 들어, 외부어디조건은 X를 A에 결합하는 것과 같을 수 있습니다 먼저 A의 많은 행을 제거하여 다음을 형성할 필요가 없습니다. 하위 쿼리의 전체 논리적 출력입니다.) 그러나 동시에 계획 시간을 늘렸습니다. 여기, 5방향이 있어요 두 개의 별도 3방향 조인 문제를 대체하는 조인 문제입니다. 가능성의 수가 기하급수적으로 늘어나기 때문에, 이것은 큰 차이를 만듭니다. 기획자는 얻는 것을 피하려고 노력한다. 하위 쿼리를 축소하지 않아 거대한 조인 검색 문제가 발생했습니다. 그 이상인 경우from_collapse_limit 발신항목은 상위 항목이 됩니다. 쿼리. 다음과 같은 방법으로 계획 시간과 계획 품질을 절충할 수 있습니다. 이 런타임 매개변수를 위아래로 조정합니다.
from_collapse_limit그리고join_collapse_limit거의 동일한 작업을 수행하기 때문에 유사한 이름이 지정됩니다. 기획자가 언제 할 것인지 제어합니다."평평하게 하다 밖으로"하위 쿼리 및 기타 제어 명시적 조인을 평면화합니다. 일반적으로 다음 중 하나를 설정합니다.join_collapse_limit같음from_collapse_limit(그래서 명시적 조인 및 하위 쿼리도 비슷하게 작동함) 또는 setjoin_collapse_limitto 1(제어하려는 경우 명시적 조인을 사용한 조인 순서). 하지만 이를 설정할 수도 있습니다. 사이의 균형을 미세 조정하려는 경우에는 다르게 설정해야 합니다. 계획 시간과 실행 시간.