Improve the efficiency of _bt_killitems. - Mailing list pgsql-hackers

From feichanghong
Subject Improve the efficiency of _bt_killitems.
Date
Msg-id tencent_E183B533F143CC2486E31F414DE9E3DD2305@qq.com
Whole thread Raw
Responses Re: Improve the efficiency of _bt_killitems.
List pgsql-hackers
Hi hackers,

In the _bt_killitems function, the following logic is present: we search to the
right for an index item that matches the heap TID and attempt to mark it as
dead. If that index item has already been marked as dead by other concurrent
processes, we will continue searching. However, there should not be any more
matching index items on the current page.

```
while (offnum <= maxoff)
{
...
/*
* Mark index item as dead, if it isn't already.  Since this
* happens while holding a buffer lock possibly in shared mode,
* it's possible that multiple processes attempt to do this
* simultaneously, leading to multiple full-page images being sent
* to WAL (if wal_log_hints or data checksums are enabled), which
* is undesirable.
*/
if (killtuple && !ItemIdIsDead(iid))
{
/* found the item/all posting list items */
ItemIdMarkDead(iid);
killedsomething = true;
break; /* out of inner search loop */
}
offnum = OffsetNumberNext(offnum);
}
```

Perhaps we should exit the current loop immediately when the killtuple is set,
stopping the search to the right. This could improve efficiency, especially
when the index item to be killed is the first one on the current page:

```
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index b4ba51357a5..529a3083165 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -4298,11 +4298,14 @@ _bt_killitems(IndexScanDesc scan)
              * to WAL (if wal_log_hints or data checksums are enabled), which
              * is undesirable.
              */
-            if (killtuple && !ItemIdIsDead(iid))
+            if (killtuple)
             {
-                /* found the item/all posting list items */
-                ItemIdMarkDead(iid);
-                killedsomething = true;
+                if (!ItemIdIsDead(iid))
+                {
+                    /* found the item/all posting list items */
+                    ItemIdMarkDead(iid);
+                    killedsomething = true;
+                }
                 break;          /* out of inner search loop */
             }
             offnum = OffsetNumberNext(offnum);
```


Best Regards,
Fei Changhong

pgsql-hackers by date:

Previous
From: Amit Langote
Date:
Subject: Re: Wrong result when enable_partitionwise_join is on if collation of PartitionKey and Column is different.
Next
From: David Rowley
Date:
Subject: Re: define pg_structiszero(addr, s, r)