diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py
index 57edebbb70..807d4b3977 100644
--- a/django/core/serializers/python.py
+++ b/django/core/serializers/python.py
@@ -74,7 +74,11 @@ class Serializer(base.Serializer):
                     return value.natural_key()
 
                 def queryset_iterator(obj, field):
-                    return getattr(obj, field.name).iterator()
+                    attr = getattr(obj, field.name)
+                    chunk_size = (
+                        2000 if getattr(attr, "prefetch_cache_name", None) else None
+                    )
+                    return attr.iterator(chunk_size)
 
             else:
 
@@ -82,12 +86,9 @@ class Serializer(base.Serializer):
                     return self._value_from_field(value, value._meta.pk)
 
                 def queryset_iterator(obj, field):
-                    return (
-                        getattr(obj, field.name)
-                        .select_related(None)
-                        .only("pk")
-                        .iterator()
-                    )
+                    query_set = getattr(obj, field.name).select_related(None).only("pk")
+                    chunk_size = 2000 if query_set._prefetch_related_lookups else None
+                    return query_set.iterator(chunk_size=chunk_size)
 
             m2m_iter = getattr(obj, "_prefetched_objects_cache", {}).get(
                 field.name,
diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py
index 5818bfaa84..3530d443b2 100644
--- a/django/core/serializers/xml_serializer.py
+++ b/django/core/serializers/xml_serializer.py
@@ -148,7 +148,11 @@ class Serializer(base.Serializer):
                     self.xml.endElement("object")
 
                 def queryset_iterator(obj, field):
-                    return getattr(obj, field.name).iterator()
+                    attr = getattr(obj, field.name)
+                    chunk_size = (
+                        2000 if getattr(attr, "prefetch_cache_name", None) else None
+                    )
+                    return attr.iterator(chunk_size)
 
             else:
 
@@ -156,12 +160,9 @@ class Serializer(base.Serializer):
                     self.xml.addQuickElement("object", attrs={"pk": str(value.pk)})
 
                 def queryset_iterator(obj, field):
-                    return (
-                        getattr(obj, field.name)
-                        .select_related(None)
-                        .only("pk")
-                        .iterator()
-                    )
+                    query_set = getattr(obj, field.name).select_related(None).only("pk")
+                    chunk_size = 2000 if query_set._prefetch_related_lookups else None
+                    return query_set.iterator(chunk_size=chunk_size)
 
             m2m_iter = getattr(obj, "_prefetched_objects_cache", {}).get(
                 field.name,
diff --git a/tests/serializers/tests.py b/tests/serializers/tests.py
index 420246db0b..9e6bb762c9 100644
--- a/tests/serializers/tests.py
+++ b/tests/serializers/tests.py
@@ -7,6 +7,7 @@ from django.core import serializers
 from django.core.serializers import SerializerDoesNotExist
 from django.core.serializers.base import ProgressBar
 from django.db import connection, transaction
+from django.db.models import Prefetch
 from django.http import HttpResponse
 from django.test import SimpleTestCase, override_settings, skipUnlessDBFeature
 from django.test.utils import Approximate
@@ -18,6 +19,7 @@ from .models import (
     AuthorProfile,
     BaseModel,
     Category,
+    CategoryMetaData,
     Child,
     ComplexModel,
     Movie,
@@ -275,18 +277,45 @@ class SerializersTestBase:
             serializers.serialize(self.serializer_name, [mv])
 
     def test_serialize_prefetch_related_m2m(self):
-        # One query for the Article table and one for each prefetched m2m
-        # field.
-        with self.assertNumQueries(4):
+        # One query for the Article table, one for each prefetched m2m
+        # field, and one extra one for the nested prefetch for the Topics
+        # that have a relationship to the Category.
+        with self.assertNumQueries(5):
             serializers.serialize(
                 self.serializer_name,
-                Article.objects.prefetch_related("categories", "meta_data", "topics"),
+                Article.objects.prefetch_related(
+                    "meta_data",
+                    "topics",
+                    Prefetch(
+                        "categories",
+                        queryset=Category.objects.prefetch_related("topic_set"),
+                    ),
+                ),
             )
         # One query for the Article table, and three m2m queries for each
         # article.
         with self.assertNumQueries(7):
             serializers.serialize(self.serializer_name, Article.objects.all())
 
+    def test_serialize_prefetch_related_m2m_with_natural_keys(self):
+        # One query for the Article table, one for each prefetched m2m
+        # field, and a query to get the categories for each Article (two in
+        # total).
+        with self.assertNumQueries(5):
+            serializers.serialize(
+                self.serializer_name,
+                Article.objects.prefetch_related(
+                    Prefetch(
+                        "meta_data",
+                        queryset=CategoryMetaData.objects.prefetch_related(
+                            "category_set"
+                        ),
+                    ),
+                    "topics",
+                ),
+                use_natural_foreign_keys=True,
+            )
+
     def test_serialize_with_null_pk(self):
         """
         Serialized data with no primary key results