博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PostgreSQL在何处处理 sql查询之四十
阅读量:5863 次
发布时间:2019-06-19

本文共 7671 字,大约阅读时间需要 25 分钟。

接前面,看 SeqNext 函数:

/* ---------------------------------------------------------------- *        SeqNext * *        This is a workhorse for ExecSeqScan * ---------------------------------------------------------------- */static TupleTableSlot *SeqNext(SeqScanState *node){    HeapTuple    tuple;    HeapScanDesc scandesc;    EState       *estate;    ScanDirection direction;    TupleTableSlot *slot;    /*     * get information from the estate and scan state     */    scandesc = node->ss_currentScanDesc;    estate = node->ps.state;    direction = estate->es_direction;    slot = node->ss_ScanTupleSlot;    /*     * get the next tuple from the table     */    tuple = heap_getnext(scandesc, direction);    /*     * save the tuple and the buffer returned to us by the access methods in     * our scan tuple slot and return the slot.  Note: we pass 'false' because     * tuples returned by heap_getnext() are pointers onto disk pages and were     * not created with palloc() and so should not be pfree()'d.  Note also     * that ExecStoreTuple will increment the refcount of the buffer; the     * refcount will not be dropped until the tuple table slot is cleared.     */    if (tuple)        ExecStoreTuple(tuple,    /* tuple to store */                       slot,    /* slot to store in */                       scandesc->rs_cbuf,        /* buffer associated with this                                                 * tuple */                       false);    /* don't pfree this pointer */    else        ExecClearTuple(slot);    return slot;}

先来看看 tuple 的数据结构:

/* * HeapTupleData is an in-memory data structure that points to a tuple. * * There are several ways in which this data structure is used: * * * Pointer to a tuple in a disk buffer: t_data points directly into the *     buffer (which the code had better be holding a pin on, but this is not *     reflected in HeapTupleData itself). * * * Pointer to nothing: t_data is NULL.  This is used as a failure indication *     in some functions. * * * Part of a palloc'd tuple: the HeapTupleData itself and the tuple *     form a single palloc'd chunk.  t_data points to the memory location *     immediately following the HeapTupleData struct (at offset HEAPTUPLESIZE). *     This is the output format of heap_form_tuple and related routines. * * * Separately allocated tuple: t_data points to a palloc'd chunk that *     is not adjacent to the HeapTupleData.    (This case is deprecated since *     it's difficult to tell apart from case #1.  It should be used only in *     limited contexts where the code knows that case #1 will never apply.) * * * Separately allocated minimal tuple: t_data points MINIMAL_TUPLE_OFFSET *     bytes before the start of a MinimalTuple.    As with the previous case, *     this can't be told apart from case #1 by inspection; code setting up *     or destroying this representation has to know what it's doing. * * t_len should always be valid, except in the pointer-to-nothing case. * t_self and t_tableOid should be valid if the HeapTupleData points to * a disk buffer, or if it represents a copy of a tuple on disk.  They * should be explicitly set invalid in manufactured tuples. */typedef struct HeapTupleData{    uint32          t_len;            /* length of *t_data */    ItemPointerData t_self;        /* SelfItemPointer */    Oid             t_tableOid;        /* table the tuple came from */    HeapTupleHeader t_data;        /* -> tuple header and data */} HeapTupleData;typedef HeapTupleData *HeapTuple;

实际测试 ,

select id from tst04 where id>1, tuple 长度 32。

select id from tst01 where id<10 , tuple 长度 28。

运行如下查询可以看到同样的结果:

postgres=# select pg_column_size(t) from tst01 t limit 1; pg_column_size ----------------             28(1 row)postgres=# select pg_column_size(t) from tst04 t limit 1; pg_column_size ----------------             32(1 row)postgres=#

也就是说,tuple 的长度包含了 附属信息的长度和字段本身内容所占的长度(integer 4字节)。

看下一层面的结构:

/* * ItemPointer: * * This is a pointer to an item within a disk page of a known file * (for example, a cross-link from an index to its parent table). * blkid tells us which block, posid tells us which entry in the linp * (ItemIdData) array we want. * * Note: because there is an item pointer in each tuple header and index * tuple header on disk, it's very important not to waste space with * structure padding bytes.  The struct is designed to be six bytes long * (it contains three int16 fields) but a few compilers will pad it to * eight bytes unless coerced.    We apply appropriate persuasion where * possible, and to cope with unpersuadable compilers, we try to use * "SizeOfIptrData" rather than "sizeof(ItemPointerData)" when computing * on-disk sizes. */typedef struct ItemPointerData{    BlockIdData ip_blkid;    OffsetNumber ip_posid;}#ifdef __arm____attribute__((packed))            /* Appropriate whack upside the head for ARM */#endifItemPointerData;

在 ItemPointerData中,估计 ip_blkid 是块号, ip_posid是 块内的本条记录所在序号。

再下一层:

typedef struct BlockIdData{    uint16        bi_hi;    uint16        bi_lo;} BlockIdData;
/* * OffsetNumber: * * this is a 1-based index into the linp (ItemIdData) array in the * header of each disk page. */typedef uint16 OffsetNumber;

在上面的SeqNext里,加入下列调试内容:

...    /*     * get the next tuple from the table     */    tuple = heap_getnext(scandesc, direction);    if (tuple)    {        fprintf(stderr,"tuple's length is: %d\n",(int)(tuple->t_len));        fprintf(stderr,"tuple's block number hi is: %d...lo is %d \n",                tuple->t_self.ip_blkid.bi_hi, tuple->t_self.ip_blkid.bi_lo);        fprintf(stderr, "tuple's offset number is : %d\n", tuple->t_self.ip_posid);        fprintf(stderr, "-------------------------------\n\n\n");    }...

看看结果:

postgres=# select id from tst04 where id>1; id ----  4  3  2(3 rows)postgres=#
tuple's length is: 32tuple's block number hi is: 0...lo is 0 tuple's offset number is : 1-------------------------------tuple's length is: 32tuple's block number hi is: 0...lo is 0 tuple's offset number is : 2-------------------------------tuple's length is: 32tuple's block number hi is: 0...lo is 0 tuple's offset number is : 3-------------------------------tuple's length is: 32tuple's block number hi is: 0...lo is 0 tuple's offset number is : 4-------------------------------

 再看  HeapTupleData 的 t_tableoid:

先看 tst04 的 oid:

postgres=# select oid from pg_class where relname='tst04';  oid  ------- 16393(1 row)postgres=#

再加入调试信息:

... /*     * get the next tuple from the table     */    tuple = heap_getnext(scandesc, direction);    if (tuple)    {        fprintf(stderr,"tuple's length is: %d\n",(int)(tuple->t_len));        fprintf(stderr,"tuple's block number hi is: %d...lo is %d \n",                tuple->t_self.ip_blkid.bi_hi, tuple->t_self.ip_blkid.bi_lo);        fprintf(stderr, "tuple's offset number is : %d\n", tuple->t_self.ip_posid);        fprintf(stderr, "tuple's table oid is: %d\n",tuple->t_tableOid);        fprintf(stderr, "-------------------------------\n\n\n");    }     ...

然后,我再看运行的情况:

postgres=# select id from tst04 where id>1; id ----  4  3  2(3 rows)postgres=#
tuple's length is: 32tuple's block number hi is: 0...lo is 0 tuple's offset number is : 1tuple's table oid is: 16393-------------------------------tuple's length is: 32tuple's block number hi is: 0...lo is 0 tuple's offset number is : 2tuple's table oid is: 16393-------------------------------tuple's length is: 32tuple's block number hi is: 0...lo is 0 tuple's offset number is : 3tuple's table oid is: 16393-------------------------------tuple's length is: 32tuple's block number hi is: 0...lo is 0 tuple's offset number is : 4tuple's table oid is: 16393-------------------------------

 

转载地址:http://rxunx.baihongyu.com/

你可能感兴趣的文章
keeplived配置
查看>>
光源、照明方法、相机与镜头配套原则、PPI
查看>>
iptables 规则保存
查看>>
zookeeper 的权限控制
查看>>
Flask实现基于角色的访问控制(RBAC)
查看>>
CSS 预处理器中的循环
查看>>
XSS 绕过过滤器大全,
查看>>
连接打印机服务器
查看>>
17. Python 生成式 生成器 迭代器
查看>>
3 . python Collections -- Deque Object
查看>>
参加第六届“飞思卡尔”全国大学生智能车有感
查看>>
转载如何具体优化网站关键词的?(一)
查看>>
鼠标样式
查看>>
Android Studio - 第四十三期 RecyclerView存在大量Item时,当滚到底部时快速滑到顶部...
查看>>
appium自动化程序教程
查看>>
adb操作命令详解及大全
查看>>
RouterOS 软路由安装与设置
查看>>
MySQL数据库的优化
查看>>
552, '5.3.4 Message size exceeds fixed limit‘’
查看>>
bugfree使用xampp安装在linux下时如何进入mysql
查看>>