diff --git a/arkindex/documents/api/elements.py b/arkindex/documents/api/elements.py
index abbce03c9a60f58fb42f1eb5f9893a2216c7caea..275869e62bdf8e09605d19cc98190644451493e0 100644
--- a/arkindex/documents/api/elements.py
+++ b/arkindex/documents/api/elements.py
@@ -1180,6 +1180,8 @@ class ElementBulkCreate(CreateAPIView):
             .objects
             .using('default')
             .filter(
+                # Using __overlap before __last makes Postgres use the GIN index instead of scanning the whole table
+                path__overlap=[self.element.id],
                 path__last=self.element.id,
                 element__type_id__in=set(element_data['type'] for element_data in elements)
             )
diff --git a/arkindex/documents/api/iiif.py b/arkindex/documents/api/iiif.py
index 3fdc5d99b7a48f9dd266d7327540ae5532490f02..e40e16065ffe810c9140e39e8cae29b989d57df1 100644
--- a/arkindex/documents/api/iiif.py
+++ b/arkindex/documents/api/iiif.py
@@ -97,6 +97,7 @@ class TranscriptionSearchAnnotationList(SearchAPIMixin, RetrieveAPIView):
                 element=list(
                     Element.objects
                            .filter(
+                               paths__path__overlap=[self.get_element().id],
                                paths__path__last=self.get_element().id,
                                type__folder=False,
                                zone__isnull=False,
diff --git a/arkindex/documents/api/ml.py b/arkindex/documents/api/ml.py
index 059e7c31d6087143a21f0ced718b481af8961848..cf67154b453a5e62ca268b778974f325b6bc1340 100644
--- a/arkindex/documents/api/ml.py
+++ b/arkindex/documents/api/ml.py
@@ -246,6 +246,7 @@ class ElementTranscriptionsBulk(CreateAPIView):
             .filter(
                 zone__image_id=image_id,
                 type=elt_type,
+                paths__path__overlap=[self.element.id],
                 paths__path__last=self.element.id
             )
             .only('id', 'zone_id')
diff --git a/arkindex/documents/models.py b/arkindex/documents/models.py
index bf9206602c68750874304ceb44869e103c87ef12..8a55a92c952607ecb6ac0ceebe2214feb20ddc48 100644
--- a/arkindex/documents/models.py
+++ b/arkindex/documents/models.py
@@ -202,12 +202,13 @@ class Element(IndexableModel):
     def get_next_order(self, type):
         """
         Find the next ordering for a new child in ElementPath
-        Uses the primary database to avoid stale reads and duplicate orderings
+        Uses the primary database to avoid stale reads and duplicate orderings,
+        and path__overlap to let Postgres use the GIN index before filtering by last item.
         """
         assert isinstance(type, ElementType)
         return ElementPath.objects \
                           .using('default') \
-                          .filter(path__last=self.id, element__type=type) \
+                          .filter(path__overlap=[self.id], path__last=self.id, element__type=type) \
                           .aggregate(max=models.Max('ordering') + 1)['max'] or 0
 
     @transaction.atomic