Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd28dff3

Browse files
committed
Introduce CompactAttribute array in TupleDesc
The new compact_attrs array stores a few select fields fromFormData_pg_attribute in a more compact way, using only 16 bytes percolumn instead of the 104 bytes that FormData_pg_attribute uses. UsingCompactAttribute allows performance-critical operations such as tupledeformation to be performed without looking at the FormData_pg_attributeelement in TupleDesc which means fewer cacheline accesses. With thischange, NAMEDATALEN could be increased with a much smaller negative impacton performance.For some workloads, tuple deformation can be the most CPU intensive partof processing the query. Some testing with 16 columns on a tablewhere the first column is variable length showed around a 10% increase intransactions per second for an OLAP type query performing aggregation onthe 16th column. However, in certain cases, the increases were muchhigher, up to ~25% on one AMD Zen4 machine.This also makes pg_attribute.attcacheoff redundant. A follow-on commitwill remove it, thus shrinking the FormData_pg_attribute struct by 4bytes.Author: David RowleyDiscussion:https://postgr.es/m/CAApHDvrBztXP3yx=NKNmo3xwFAFhEdyPnvrDg3=M0RhDs+4vYw@mail.gmail.comReviewed-by: Andres Freund, Victor Yegorov
1 parente4c8865 commitd28dff3

File tree

14 files changed

+246
-68
lines changed

14 files changed

+246
-68
lines changed

‎src/backend/access/common/heaptuple.c‎

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@
8383
#defineVARLENA_ATT_IS_PACKABLE(att) \
8484
((att)->attstorage != TYPSTORAGE_PLAIN)
8585

86+
/* FormData_pg_attribute.attstorage != TYPSTORAGE_PLAIN and an attlen of -1 */
87+
#defineCOMPACT_ATTR_IS_PACKABLE(att) \
88+
((att)->attlen == -1 && (att)->attispackable)
89+
8690
/*
8791
* Setup for caching pass-by-ref missing attributes in a way that survives
8892
* tupleDesc destruction.
@@ -147,12 +151,12 @@ Datum
147151
getmissingattr(TupleDesctupleDesc,
148152
intattnum,bool*isnull)
149153
{
150-
Form_pg_attributeatt;
154+
CompactAttribute*att;
151155

152156
Assert(attnum <=tupleDesc->natts);
153157
Assert(attnum>0);
154158

155-
att=TupleDescAttr(tupleDesc,attnum-1);
159+
att=TupleDescCompactAttr(tupleDesc,attnum-1);
156160

157161
if (att->atthasmissing)
158162
{
@@ -223,15 +227,15 @@ heap_compute_data_size(TupleDesc tupleDesc,
223227
for (i=0;i<numberOfAttributes;i++)
224228
{
225229
Datumval;
226-
Form_pg_attributeatti;
230+
CompactAttribute*atti;
227231

228232
if (isnull[i])
229233
continue;
230234

231235
val=values[i];
232-
atti=TupleDescAttr(tupleDesc,i);
236+
atti=TupleDescCompactAttr(tupleDesc,i);
233237

234-
if (ATT_IS_PACKABLE(atti)&&
238+
if (COMPACT_ATTR_IS_PACKABLE(atti)&&
235239
VARATT_CAN_MAKE_SHORT(DatumGetPointer(val)))
236240
{
237241
/*
@@ -268,7 +272,7 @@ heap_compute_data_size(TupleDesc tupleDesc,
268272
* Fill in either a data value or a bit in the null bitmask
269273
*/
270274
staticinlinevoid
271-
fill_val(Form_pg_attributeatt,
275+
fill_val(CompactAttribute*att,
272276
bits8**bit,
273277
int*bitmask,
274278
char**dataP,
@@ -349,8 +353,7 @@ fill_val(Form_pg_attribute att,
349353
data_length=VARSIZE_SHORT(val);
350354
memcpy(data,val,data_length);
351355
}
352-
elseif (VARLENA_ATT_IS_PACKABLE(att)&&
353-
VARATT_CAN_MAKE_SHORT(val))
356+
elseif (att->attispackable&&VARATT_CAN_MAKE_SHORT(val))
354357
{
355358
/* convert to short varlena -- no alignment */
356359
data_length=VARATT_CONVERTED_SHORT_SIZE(val);
@@ -427,7 +430,7 @@ heap_fill_tuple(TupleDesc tupleDesc,
427430

428431
for (i=0;i<numberOfAttributes;i++)
429432
{
430-
Form_pg_attributeattr=TupleDescAttr(tupleDesc,i);
433+
CompactAttribute*attr=TupleDescCompactAttr(tupleDesc,i);
431434

432435
fill_val(attr,
433436
bitP ?&bitP :NULL,
@@ -461,7 +464,8 @@ heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
461464
Assert(!tupleDesc||attnum <=tupleDesc->natts);
462465
if (attnum> (int)HeapTupleHeaderGetNatts(tup->t_data))
463466
{
464-
if (tupleDesc&&TupleDescAttr(tupleDesc,attnum-1)->atthasmissing)
467+
if (tupleDesc&&
468+
TupleDescCompactAttr(tupleDesc,attnum-1)->atthasmissing)
465469
return false;
466470
else
467471
return true;
@@ -570,13 +574,13 @@ nocachegetattr(HeapTuple tup,
570574

571575
if (!slow)
572576
{
573-
Form_pg_attributeatt;
577+
CompactAttribute*att;
574578

575579
/*
576580
* If we get here, there are no nulls up to and including the target
577581
* attribute. If we have a cached offset, we can use it.
578582
*/
579-
att=TupleDescAttr(tupleDesc,attnum);
583+
att=TupleDescCompactAttr(tupleDesc,attnum);
580584
if (att->attcacheoff >=0)
581585
returnfetchatt(att,tp+att->attcacheoff);
582586

@@ -591,7 +595,7 @@ nocachegetattr(HeapTuple tup,
591595

592596
for (j=0;j <=attnum;j++)
593597
{
594-
if (TupleDescAttr(tupleDesc,j)->attlen <=0)
598+
if (TupleDescCompactAttr(tupleDesc,j)->attlen <=0)
595599
{
596600
slow= true;
597601
break;
@@ -614,18 +618,18 @@ nocachegetattr(HeapTuple tup,
614618
* fixed-width columns, in hope of avoiding future visits to this
615619
* routine.
616620
*/
617-
TupleDescAttr(tupleDesc,0)->attcacheoff=0;
621+
TupleDescCompactAttr(tupleDesc,0)->attcacheoff=0;
618622

619623
/* we might have set some offsets in the slow path previously */
620-
while (j<natts&&TupleDescAttr(tupleDesc,j)->attcacheoff>0)
624+
while (j<natts&&TupleDescCompactAttr(tupleDesc,j)->attcacheoff>0)
621625
j++;
622626

623-
off=TupleDescAttr(tupleDesc,j-1)->attcacheoff+
624-
TupleDescAttr(tupleDesc,j-1)->attlen;
627+
off=TupleDescCompactAttr(tupleDesc,j-1)->attcacheoff+
628+
TupleDescCompactAttr(tupleDesc,j-1)->attlen;
625629

626630
for (;j<natts;j++)
627631
{
628-
Form_pg_attributeatt=TupleDescAttr(tupleDesc,j);
632+
CompactAttribute*att=TupleDescCompactAttr(tupleDesc,j);
629633

630634
if (att->attlen <=0)
631635
break;
@@ -639,7 +643,7 @@ nocachegetattr(HeapTuple tup,
639643

640644
Assert(j>attnum);
641645

642-
off=TupleDescAttr(tupleDesc,attnum)->attcacheoff;
646+
off=TupleDescCompactAttr(tupleDesc,attnum)->attcacheoff;
643647
}
644648
else
645649
{
@@ -659,7 +663,7 @@ nocachegetattr(HeapTuple tup,
659663
off=0;
660664
for (i=0;;i++)/* loop exit is at "break" */
661665
{
662-
Form_pg_attributeatt=TupleDescAttr(tupleDesc,i);
666+
CompactAttribute*att=TupleDescCompactAttr(tupleDesc,i);
663667

664668
if (HeapTupleHasNulls(tup)&&att_isnull(i,bp))
665669
{
@@ -707,7 +711,7 @@ nocachegetattr(HeapTuple tup,
707711
}
708712
}
709713

710-
returnfetchatt(TupleDescAttr(tupleDesc,attnum),tp+off);
714+
returnfetchatt(TupleDescCompactAttr(tupleDesc,attnum),tp+off);
711715
}
712716

713717
/* ----------------
@@ -892,7 +896,7 @@ expand_tuple(HeapTuple *targetHeapTuple,
892896
{
893897
if (attrmiss[attnum].am_present)
894898
{
895-
Form_pg_attributeatt=TupleDescAttr(tupleDesc,attnum);
899+
CompactAttribute*att=TupleDescCompactAttr(tupleDesc,attnum);
896900

897901
targetDataLen=att_align_datum(targetDataLen,
898902
att->attalign,
@@ -1020,8 +1024,7 @@ expand_tuple(HeapTuple *targetHeapTuple,
10201024
/* Now fill in the missing values */
10211025
for (attnum=sourceNatts;attnum<natts;attnum++)
10221026
{
1023-
1024-
Form_pg_attributeattr=TupleDescAttr(tupleDesc,attnum);
1027+
CompactAttribute*attr=TupleDescCompactAttr(tupleDesc,attnum);
10251028

10261029
if (attrmiss&&attrmiss[attnum].am_present)
10271030
{
@@ -1370,7 +1373,7 @@ heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,
13701373

13711374
for (attnum=0;attnum<natts;attnum++)
13721375
{
1373-
Form_pg_attributethisatt=TupleDescAttr(tupleDesc,attnum);
1376+
CompactAttribute*thisatt=TupleDescCompactAttr(tupleDesc,attnum);
13741377

13751378
if (hasnulls&&att_isnull(attnum,bp))
13761379
{

‎src/backend/access/common/indextuple.c‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -303,13 +303,13 @@ nocache_index_getattr(IndexTuple tup,
303303

304304
if (!slow)
305305
{
306-
Form_pg_attributeatt;
306+
CompactAttribute*att;
307307

308308
/*
309309
* If we get here, there are no nulls up to and including the target
310310
* attribute. If we have a cached offset, we can use it.
311311
*/
312-
att=TupleDescAttr(tupleDesc,attnum);
312+
att=TupleDescCompactAttr(tupleDesc,attnum);
313313
if (att->attcacheoff >=0)
314314
returnfetchatt(att,tp+att->attcacheoff);
315315

@@ -324,7 +324,7 @@ nocache_index_getattr(IndexTuple tup,
324324

325325
for (j=0;j <=attnum;j++)
326326
{
327-
if (TupleDescAttr(tupleDesc,j)->attlen <=0)
327+
if (TupleDescCompactAttr(tupleDesc,j)->attlen <=0)
328328
{
329329
slow= true;
330330
break;
@@ -347,18 +347,18 @@ nocache_index_getattr(IndexTuple tup,
347347
* fixed-width columns, in hope of avoiding future visits to this
348348
* routine.
349349
*/
350-
TupleDescAttr(tupleDesc,0)->attcacheoff=0;
350+
TupleDescCompactAttr(tupleDesc,0)->attcacheoff=0;
351351

352352
/* we might have set some offsets in the slow path previously */
353-
while (j<natts&&TupleDescAttr(tupleDesc,j)->attcacheoff>0)
353+
while (j<natts&&TupleDescCompactAttr(tupleDesc,j)->attcacheoff>0)
354354
j++;
355355

356-
off=TupleDescAttr(tupleDesc,j-1)->attcacheoff+
357-
TupleDescAttr(tupleDesc,j-1)->attlen;
356+
off=TupleDescCompactAttr(tupleDesc,j-1)->attcacheoff+
357+
TupleDescCompactAttr(tupleDesc,j-1)->attlen;
358358

359359
for (;j<natts;j++)
360360
{
361-
Form_pg_attributeatt=TupleDescAttr(tupleDesc,j);
361+
CompactAttribute*att=TupleDescCompactAttr(tupleDesc,j);
362362

363363
if (att->attlen <=0)
364364
break;
@@ -372,7 +372,7 @@ nocache_index_getattr(IndexTuple tup,
372372

373373
Assert(j>attnum);
374374

375-
off=TupleDescAttr(tupleDesc,attnum)->attcacheoff;
375+
off=TupleDescCompactAttr(tupleDesc,attnum)->attcacheoff;
376376
}
377377
else
378378
{
@@ -392,7 +392,7 @@ nocache_index_getattr(IndexTuple tup,
392392
off=0;
393393
for (i=0;;i++)/* loop exit is at "break" */
394394
{
395-
Form_pg_attributeatt=TupleDescAttr(tupleDesc,i);
395+
CompactAttribute*att=TupleDescCompactAttr(tupleDesc,i);
396396

397397
if (IndexTupleHasNulls(tup)&&att_isnull(i,bp))
398398
{
@@ -440,7 +440,7 @@ nocache_index_getattr(IndexTuple tup,
440440
}
441441
}
442442

443-
returnfetchatt(TupleDescAttr(tupleDesc,attnum),tp+off);
443+
returnfetchatt(TupleDescCompactAttr(tupleDesc,attnum),tp+off);
444444
}
445445

446446
/*
@@ -490,7 +490,7 @@ index_deform_tuple_internal(TupleDesc tupleDescriptor,
490490

491491
for (attnum=0;attnum<natts;attnum++)
492492
{
493-
Form_pg_attributethisatt=TupleDescAttr(tupleDescriptor,attnum);
493+
CompactAttribute*thisatt=TupleDescCompactAttr(tupleDescriptor,attnum);
494494

495495
if (hasnulls&&att_isnull(attnum,bp))
496496
{
@@ -588,7 +588,7 @@ index_truncate_tuple(TupleDesc sourceDescriptor, IndexTuple source,
588588
returnCopyIndexTuple(source);
589589

590590
/* Create temporary descriptor to scribble on */
591-
truncdesc=palloc(TupleDescSize(sourceDescriptor));
591+
truncdesc=CreateTemplateTupleDesc(sourceDescriptor->natts);
592592
TupleDescCopy(truncdesc,sourceDescriptor);
593593
truncdesc->natts=leavenatts;
594594

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp