[CBRD-27138] Report the optimizer giving up on a join too wide to index - #7724
Open
soheejung-cs wants to merge 2 commits into
Open
[CBRD-27138] Report the optimizer giving up on a join too wide to index#7724soheejung-cs wants to merge 2 commits into
soheejung-cs wants to merge 2 commits into
Conversation
qo_discover_partitions () aborts optimization when a partition holds more nodes than the join_info vector can index -- the vector is indexed by a subset bitmask of the partition's nodes, so it holds 2**nodes entries and its byte size stops fitting in a signed int past _WORDSIZE - 2 - LOG2_SIZEOF_POINTER (27) nodes. The statement then runs with the syntactic join order, which is a legitimate fallback, but it happened without a word to the user: a 28-table query silently lost cost-based join ordering and index selection where a 27-table one kept it, and the only observable difference was that the plan dump printed nothing. Report it in the two places a user looks. The abort now raises the existing (until now unused) ER_QO_SET_SIZE_EXCEEDED warning -- 'Query involves too many items for optimizer.' -- so the error log records it, with the node count and the limit in the debug log beside it. And when a plan dump was requested but no plan exists, the dump says the plan was not generated instead of omitting the section, so its absence is no longer indistinguishable from the dump being off. The limit itself is unchanged: removing it needs the subset-indexed join_info vector replaced by a hash map, which is a separate change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJG3W9JhvjYKRe5GUzbb6m
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
❌ TC Merge Gate — Merge BlockedOne or more TC PRs are still open. Please merge or close them before merging this PR. TC Repositories & Branches:
Steps to unblock:
|
🧪 TC Test Environment ReadyCircleCI Testing:
TC Repositories & Branches:
Next Steps:
|
Contributor
|
Reviews (1): Last reviewed commit: "[CBRD-27138] Report the optimizer giving..." | Re-trigger Greptile |
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Contributor
Author
|
/run all |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
http://jira.cubrid.org/browse/CBRD-27138
Purpose
qo_discover_partitions ()는 한 파티션의 노드 수가_WORDSIZE - 2 - LOG2_SIZEOF_POINTER(= 27)를 넘으면QO_ABORT로 최적화 전체를 중단한다. 질의는 구문 순서 그대로의 조인 플랜으로 실행되므로 결과는 정상이지만 비용 기반 조인 순서·인덱스 선택이 통째로 사라진다.문제는 그것이 사용자에게 전혀 알려지지 않는다는 점이었다. 27테이블 질의는 최적화되고 28테이블 질의는 최적화되지 않는데, 관측 가능한 차이는 "플랜 덤프가 안 나온다"는 것뿐이고 그마저 덤프를 껐을 때와 구분되지 않는다. BI 도구·ORM이 만드는 질의에서 실제로 28테이블 경계를 넘나들기 때문에, 27→28에서 성능이 절벽처럼 떨어지고 원인을 짚을 단서가 없었다.
이 PR은 한계를 넘겼다는 사실을 보이게 만든다. 한계 자체는 그대로다.
Implementation
1. abort 지점에서 알림 기록 (
query_graph.c)ER_QO_SET_SIZE_EXCEEDED(-470)는 정의만 있고 지금까지 아무 곳에서도 쓰이지 않던 코드이고, 메시지가Query involves too many items for optimizer.로 이 상황 그대로다. 새 에러코드를 추가하지 않았다(6곳 갱신·CCI 동기화 불필요).error_log_warning이 기본 off라(error_manager.c의 severity 필터) 기본 설정에서 로그에 남지 않아 "조용히 비활성화"라는 증상이 그대로 남는다. notification은 기본 기록되고, 클라이언트에 에러 상태를 남기지 않으므로 질의는 이전과 똑같이 구문 순서 플랜으로 실행된다.2. 플랜 덤프에 사유 출력 (
xasl_generation.c)덤프를 요청했는데(
SET OPTIMIZATION LEVEL) 플랜이 없으면 섹션을 생략하지 않고 다음을 출력한다.이 경로는 노드 한계 외에 할당 실패·내부 assertion 실패로 최적화가 중단된 경우도 함께 덮는다.
Verification
JIRA 재현 절차대로 27·28테이블 체인 조인(각 1행, PK, 통계 수집), release 빌드,
SET OPTIMIZATION LEVEL 513:Query plan:+ 플랜 본문 (기존과 동일)Query plan: (not generated -- cost-based optimization was skipped for this query)NOTIFICATION ... CODE = -470/Query involves too many items for optimizer.두 경우 모두 질의는 정상 수행되고 결과 행도 동일하다(28테이블은 이전처럼 구문 순서 플랜).
Remarks
join_info벡터를 파티션 노드의 부분집합 비트마스크로 색인하므로 항목 수가2**nodes이고, 바이트 크기가 signed int를 넘는 지점이 27이다. 한계를 없애려면 이 벡터를 해시맵으로 바꿔야 하고, 그것은 별도 변경이다.qo_search_partition_join ()안의 탐색 깊이 산정이고, 이 abort는 그 함수가 호출되기 전 파티션 발견 단계에서 일어난다. 28테이블 질의는 예산 계산에 도달조차 하지 않는다.SET OPTIMIZATION LEVEL로 덤프를 켠 상태에서 최적화가 중단되는 질의를 가진 케이스가 있다면 그 답안에 한 줄이 추가된다(현재 테스트 스위트에는 28테이블 이상 조인 케이스가 없다).