本节介绍排序的实现,排序的实现函数是ExecSort,与聚合函数类似,也有要一个初始化的过程ExecInitSort,本节主要介绍该函数的实现.
下面是测试SQL执行排序的计划树:
",,,,,"select bh,c1 from t_sort order by t_sort;",,,"psql"
2019-05-17 15:12:42.494 CST,"xdb","testdb",1519,"[local]",5cde5e9e.5ef,15,"SELECT",2019-05-17 15:11:26 CST,3/10,0,LOG,00000,"plan:"," {PLANNEDSTMT
:commandType 1
:queryId 0
:hasReturning false
:hasModifyingCTE false
:canSetTag true
:transientPlan false
:dependsOnRole false
:parallelModeNeeded false
:jitFlags 0
:planTree
{SORT
:startup_cost 14142.82
:total_cost 14392.82
:plan_rows 100000
:plan_width 66
:parallel_aware false
:parallel_safe true
:plan_node_id 0
:targetlist (...
)
:qual <>
:lefttree
{SEQSCAN
:startup_cost 0.00
:total_cost 1736.00
:plan_rows 100000
:plan_width 66
:parallel_aware false
:parallel_safe true
:plan_node_id 1
:targetlist (...
)
:qual <>
:lefttree <>
:righttree <>
:initPlan <>
:extParam (b)
:allParam (b)
:scanrelid 1
}
:righttree <>
:initPlan <>
:extParam (b)
:allParam (b)
:numCols 1
:sortColIdx 3
:sortOperators 2990
:collations 0
:nullsFirst false
}
:rtable (...
)
:resultRelations <>
:nonleafResultRelations <>
:rootResultRelations <>
:subplans <>
:rewindPlanIDs (b)
:rowMarks <>
:relationOids (o 278567)
:invalItems <>
:paramExecTypes <>
:utilityStmt <>
:stmt_location 0
:stmt_len 40
}
",,,,,"select bh,c1 from t_sort order by t_sort;",,,"psql"
一、数据结构
SortState
排序运行期状态信息
typedef struct SortState
{
//基类
ScanState ss;
//是否需要随机访问排序输出?
bool randomAccess;
//结果集是否存在边界?
bool bounded;
//如存在边界,需要多少个元组?
int64 bound;
//是否已完成排序?
bool sort_Done;
//是否使用有界值?
bool bounded_Done;
//使用的有界值?
int64 bound_Done;
//tuplesort.c的私有状态
void *tuplesortstate;
//是否worker?
bool am_worker;
//每个worker对应一个条目
SharedSortInfo *shared_info;
} SortState;
typedef struct SharedSortInfo
{
//worker个数?
int num_workers;
//排序机制
TuplesortInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
} SharedSortInfo;
TuplesortInstrumentation
报告排序统计的数据结构.
typedef enum
{
SORT_TYPE_STILL_IN_PROGRESS = 0,//仍然在排序中
SORT_TYPE_TOP_N_HEAPSORT,//TOP N 堆排序
SORT_TYPE_QUICKSORT,//快速排序
SORT_TYPE_EXTERNAL_SORT,//外部排序
SORT_TYPE_EXTERNAL_MERGE//外部排序后的合并
} TuplesortMethod;//排序方法
typedef enum
{
SORT_SPACE_TYPE_DISK,//需要用上磁盘
SORT_SPACE_TYPE_MEMORY//使用内存
} TuplesortSpaceType;
typedef struct TuplesortInstrumentation
{
//使用的排序算法
TuplesortMethod sortMethod;
//排序使用空间类型
TuplesortSpaceType spaceType;
//空间消耗(以K为单位)
long spaceUsed;
} TuplesortInstrumentation;
二、源码解读
ExecInitSort为排序节点创建运行期信息并初始化outer子树,逻辑较为简单.
SortState *
ExecInitSort(Sort *node, EState *estate, int eflags)
{
SortState *sortstate;//排序运行期信息
SO1_printf("ExecInitSort: %s\n",
"initializing sort node");
sortstate = makeNode(SortState);
sortstate->ss.ps.plan = (Plan *) node;
sortstate->ss.ps.state = estate;
sortstate->ss.ps.ExecProcNode = ExecSort;
sortstate->randomAccess = (eflags & (EXEC_FLAG_REWIND |
EXEC_FLAG_BACKWARD |
EXEC_FLAG_MARK)) != 0;
sortstate->bounded = false;//结果集不存在边界
sortstate->sort_Done = false;//未完成排序
sortstate->tuplesortstate = NULL;//元组排序状态为NULL
eflags &= ~(EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK);
//外(左)子节点往往是扫描节点,如SeqScan等
outerPlanState(sortstate) = ExecInitNode(outerPlan(node), estate, eflags);
ExecCreateScanSlotFromOuterPlan(estate, &sortstate->ss);
ExecInitResultTupleSlotTL(estate, &sortstate->ss.ps);
sortstate->ss.ps.ps_ProjInfo = NULL;
SO1_printf("ExecInitSort: %s\n",
"sort node initialized");
return sortstate;
}
void
ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate)
{
PlanState *outerPlan;
TupleDesc tupDesc;
outerPlan = outerPlanState(scanstate);
tupDesc = ExecGetResultType(outerPlan);
ExecInitScanTupleSlot(estate, scanstate, tupDesc);
}
void
ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc)
{
scanstate->ss_ScanTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable,
tupledesc);
scanstate->ps.scandesc = tupledesc;
}
三、跟踪分析
N/A
四、参考资料
N/A
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
软考中级精品资料免费领
- 历年真题答案解析
- 备考技巧名师总结
- 高频考点精准押题
- 资料下载
- 历年真题
193.9 KB下载数265
191.63 KB下载数245
143.91 KB下载数1148
183.71 KB下载数642
644.84 KB下载数2756
相关文章
发现更多好内容猜你喜欢
AI推送时光机PostgreSQL 源码解读(202)- 查询#115(类型转换)
数据库2024-04-02
PostgreSQL 源码解读(17)- 查询语句#2(查询优化基础)
数据库2024-04-02
PostgreSQL 源码解读(42)- 查询语句#27(等价类)
数据库2024-04-02
咦!没有更多了?去看看其它编程学习网 内容吧