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

Commitb648b70

Browse files
committed
Speed up CREATE INDEX CONCURRENTLY's TID sort.
Encode TIDs as 64-bit integers to speed up comparisons. This seems tospeed things up on all platforms, but is even more beneficial when8-byte integers are passed by value.Peter Geoghegan. Design suggestions and review by Tom Lane. Reviewalso by Simon Riggs and by me.
1 parentf27a6b1 commitb648b70

File tree

1 file changed

+67
-4
lines changed

1 file changed

+67
-4
lines changed

‎src/backend/catalog/index.c

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ static void index_update_stats(Relation rel,
109109
staticvoidIndexCheckExclusion(RelationheapRelation,
110110
RelationindexRelation,
111111
IndexInfo*indexInfo);
112+
staticinlineint64itemptr_encode(ItemPointeritemptr);
113+
staticinlinevoiditemptr_decode(ItemPointeritemptr,int64encoded);
112114
staticboolvalidate_index_callback(ItemPointeritemptr,void*opaque);
113115
staticvoidvalidate_index_heapscan(RelationheapRelation,
114116
RelationindexRelation,
@@ -2832,7 +2834,13 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot)
28322834
ivinfo.num_heap_tuples=heapRelation->rd_rel->reltuples;
28332835
ivinfo.strategy=NULL;
28342836

2835-
state.tuplesort=tuplesort_begin_datum(TIDOID,TIDLessOperator,
2837+
/*
2838+
* Encode TIDs as int8 values for the sort, rather than directly sorting
2839+
* item pointers. This can be significantly faster, primarily because TID
2840+
* is a pass-by-reference type on all platforms, whereas int8 is
2841+
* pass-by-value on most platforms.
2842+
*/
2843+
state.tuplesort=tuplesort_begin_datum(INT8OID,Int8LessOperator,
28362844
InvalidOid, false,
28372845
maintenance_work_mem,
28382846
false);
@@ -2871,15 +2879,56 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot)
28712879
heap_close(heapRelation,NoLock);
28722880
}
28732881

2882+
/*
2883+
* itemptr_encode - Encode ItemPointer as int64/int8
2884+
*
2885+
* This representation must produce values encoded as int64 that sort in the
2886+
* same order as their corresponding original TID values would (using the
2887+
* default int8 opclass to produce a result equivalent to the default TID
2888+
* opclass).
2889+
*
2890+
* As noted in validate_index(), this can be significantly faster.
2891+
*/
2892+
staticinlineint64
2893+
itemptr_encode(ItemPointeritemptr)
2894+
{
2895+
BlockNumberblock=ItemPointerGetBlockNumber(itemptr);
2896+
OffsetNumberoffset=ItemPointerGetOffsetNumber(itemptr);
2897+
int64encoded;
2898+
2899+
/*
2900+
* Use the 16 least significant bits for the offset. 32 adjacent bits are
2901+
* used for the block number. Since remaining bits are unused, there
2902+
* cannot be negative encoded values (We assume a two's complement
2903+
* representation).
2904+
*/
2905+
encoded= ((uint64)block <<16) | (uint16)offset;
2906+
2907+
returnencoded;
2908+
}
2909+
2910+
/*
2911+
* itemptr_decode - Decode int64/int8 representation back to ItemPointer
2912+
*/
2913+
staticinlinevoid
2914+
itemptr_decode(ItemPointeritemptr,int64encoded)
2915+
{
2916+
BlockNumberblock= (BlockNumber) (encoded >>16);
2917+
OffsetNumberoffset= (OffsetNumber) (encoded&0xFFFF);
2918+
2919+
ItemPointerSet(itemptr,block,offset);
2920+
}
2921+
28742922
/*
28752923
* validate_index_callback - bulkdelete callback to collect the index TIDs
28762924
*/
28772925
staticbool
28782926
validate_index_callback(ItemPointeritemptr,void*opaque)
28792927
{
28802928
v_i_state*state= (v_i_state*)opaque;
2929+
int64encoded=itemptr_encode(itemptr);
28812930

2882-
tuplesort_putdatum(state->tuplesort,PointerGetDatum(itemptr), false);
2931+
tuplesort_putdatum(state->tuplesort,Int64GetDatum(encoded), false);
28832932
state->itups+=1;
28842933
return false;/* never actually delete anything */
28852934
}
@@ -2911,6 +2960,7 @@ validate_index_heapscan(Relation heapRelation,
29112960

29122961
/* state variables for the merge */
29132962
ItemPointerindexcursor=NULL;
2963+
ItemPointerDatadecoded;
29142964
booltuplesort_empty= false;
29152965

29162966
/*
@@ -3020,13 +3070,26 @@ validate_index_heapscan(Relation heapRelation,
30203070
*/
30213071
if (ItemPointerGetBlockNumber(indexcursor)==root_blkno)
30223072
in_index[ItemPointerGetOffsetNumber(indexcursor)-1]= true;
3023-
pfree(indexcursor);
30243073
}
30253074

30263075
tuplesort_empty= !tuplesort_getdatum(state->tuplesort, true,
30273076
&ts_val,&ts_isnull);
30283077
Assert(tuplesort_empty|| !ts_isnull);
3029-
indexcursor= (ItemPointer)DatumGetPointer(ts_val);
3078+
if (!tuplesort_empty)
3079+
{
3080+
itemptr_decode(&decoded,DatumGetInt64(ts_val));
3081+
indexcursor=&decoded;
3082+
3083+
/* If int8 is pass-by-ref, free (encoded) TID Datum memory */
3084+
#ifndefUSE_FLOAT8_BYVAL
3085+
pfree(DatumGetPointer(ts_val));
3086+
#endif
3087+
}
3088+
else
3089+
{
3090+
/* Be tidy */
3091+
indexcursor=NULL;
3092+
}
30303093
}
30313094

30323095
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp