< BACK ビンテージのインデックスカード用ファイリングキャビネットの引き出しが開いており、温かみのあるタングステン光の下で、浅い被写界深度、35mm フィルムグレイン

サイトマップインデックスファイル:50,000 URL を超えるサイトマップのスケーリング

2021 年、私は 140,000 個の商品 URL を持つ WooCommerce サイトを引き継ぎました。単一の sitemap.xml はちょうど 50,000 件のエントリで頭打ちになり、Google Search Console にページのごく一部がインデックスされているだけの理由を理解できないクライアントがいました。サイトマップファイルは単に... 停止していました。エラーもなく、警告もありません。サイレント切り捨てだけです。これはインデックスに何か問題があるという可視的なシグナルを送らずにランキングを失わせる種類のものです。

サイトが 50,000 URL を超えて成長している場合、この記事はその壁にぶつかる前に読む必要があります。

50,000 URL の上限が存在する理由

Google、Bing など複数の企業が共同で管理する Sitemaps プロトコルは、単一のサイトマップファイルに対して 2 つの厳密な制約を設定しています。50,000 URL 以下、および 50MB 以下(非圧縮)です。これらは提案ではなく、ハードリミットです。Googlebot は、いずれかの制限に最初に達したところでファイルの解析を停止します。Sitemaps protocol, maintained jointly by Google, Bing, and others, sets two hard constraints on a single sitemap file: no more than 50,000 URLs, and no larger than 50MB uncompressed. These aren't suggestions. Googlebot will stop parsing the file at whichever limit it hits first.

正直なところ、50MB のシーリングはめったに問題になりません。ほとんどの URL は十分に短いため、URL カウント制限に達する前にファイルサイズ制限に達するには、ばかばかしく長いパスが必要になります。50,000 URL キャップが人々の悩みの種です。

では、カタログ、ブログアーカイブ、ユーザー生成コンテンツセクションがそのしきい値を超えた場合、あなたは何をするのか?サイトマップインデックスファイルを使う。

サイトマップインデックスファイルとは実際のところ何か

シンプルなコンセプトだ。URLを含む単一のサイトマップの代わりに、複数の子サイトマップを指す親XML ファイルを作成する。各子サイトマップは最大50,000個のURLを保持できる。インデックスファイル自体は最大50,000個の子サイトマップを参照できる。つまり理論上の上限は25億URLということだ。そこまでいくことはない。

構造は次のようになる:

`` sitemap_index.xml ├── sitemap-posts-1.xml (最大50,000ブログ記事) ├── sitemap-posts-2.xml (溢れた記事) ├── sitemap-products-1.xml (最大50,000商品) ├── sitemap-products-2.xml (溢れた商品) └── sitemap-pages.xml (静的ページ) `` sitemap_index.xml ├── sitemap-posts-1.xml (up to 50,000 blog posts) ├── sitemap-posts-2.xml (overflow posts) ├── sitemap-products-1.xml (up to 50,000 products) ├── sitemap-products-2.xml (overflow products) └── sitemap-pages.xml (static pages) ``

インデックスファイルは<urlset>の代わりに<sitemapindex>をルート要素として使う。各子は<sitemap>タグにラップされており、子ファイルを指す<loc>と、オプションで<lastmod>タイムスタンプを含む。<sitemapindex> as the root element instead of <urlset>. Each child is wrapped in a <sitemap> tag with a <loc> pointing to the child file, and optionally a <lastmod> timestamp.

Google Search Consoleに送信するのはインデックスファイルのURLで、個々の子ファイルではない。1つの送信、1つの真実の源。

URLをインテリジェントに分割する方法

ここがほとんどのチュートリアルが間違えるところだ。「ただURLを50,000個のグループにチャンク分割すればいい」と言うだけで終わらせてしまう。しかし、チャンク境界は保守性とGooglebot のクロール論理にとって重要だ。

任意の数ではなく、コンテンツタイプで分割する。常に。毎回だ。

コンテンツタイプ別に分類する

  • 製品を独立したサイトマップシリーズに配置(sitemap-products-1.xml、sitemap-products-2.xml)sitemap-products-1.xml , sitemap-products-2.xml)
  • ブログ記事を独立したシリーズに配置
  • カテゴリーページとタグページはまとめて配置(ナビゲーション要素なので1つのグループとして扱う)
  • 静的ページ(About、Contact、ランディングページ)は1つのファイルに配置、通常は1,000 URL未満

なぜこれが重要か?製品データベースが一括更新されるとき、製品サイトマップのみを再生成すればよい。製品とブログ記事が混在した単一ファイル全体を無効化・再生成する必要がない。また、Googlebotはサイトマップを順番にクロールしやすいため、タイプ別にグループ化すれば、どのような内容が見つかるかについてより明確なシグナルが得られる。

各タイプ内でページネーションを行う

コンテンツタイプが50,000 URLを超えたら、ページネーションを実装する。最初から一貫した命名規則を使う。私は sitemap-{type}-{page}.xml を使っている。ファイル名に日付を使わない。2019年にニュースサイトでこの間違いを犯してしまい、sitemap-articles-2019-march.xml のようなファイル名になってしまった。履歴コンテンツを再生成する必要が生じた瞬間に、その名前は完全に無意味になった。ページ番号で統一する。sitemap-{type}-{page}.xml . Don't use dates in the filename. I made that mistake on a news site in 2019 and ended up with filenames like sitemap-articles-2019-march.xml that became completely meaningless the moment we needed to regenerate historical content. Stick to numbered pages.

lastmod を正直に保つ

子サイトマップ内の <lastmod> 要素は、サイトマップを再生成した時点ではなく、実際にコンテンツが最後に変更された時点を反映する必要がある。再生成するたびにすべての URL に本日の日付を付与するセットアップを見かけたことがある。そのようなやり方では Googlebot に lastmod を無視するよう訓練してしまう。なぜなら、そのシグナルはノイズだからだ。CMS の実際の変更タイムスタンプを使用する。WordPress の場合、wp_posts テーブルの post_modified_gmt がそれにあたる。<lastmod> element in your child sitemaps should reflect when the content was actually last modified, not when you regenerated the sitemap. I've seen setups where every regeneration stamps every URL with today's date. That trains Googlebot to ignore your lastmod entirely because the signal is noise. Use your CMS's actual modified timestamp. In WordPress, that's post_modified_gmt from the wp_posts table.

ツール:スケール時に実際に機能するもの

Seahawkで構築するほとんどのWordPress サイトでは、実際に使用しているオプションは以下の通りです:

  1. Yoast SEOは、ポストタイプあたり1,000 URLを超えると、サイトマップインデックスを自動的に処理します。クリーンでセグメント化されたファイルを生成します。ただし、デフォルトのバッチサイズは子サイトマップあたり1,000 URLで、かなり保守的です。wpseo_sitemap_entries_per_pageでそれをフィルタリングできます。良好にホストされているサーバーでは、通常これを5,000に上げます。 handles sitemap indexes automatically once you have more than 1,000 URLs per post type. It generates clean, segmented files. But the default batch size is 1,000 URLs per child sitemap, which is conservative. You can filter that up with wpseo_sitemap_entries_per_page. I usually push it to 5,000 on well-hosted servers.
  2. Rank Mathも同じことをしますが、どのポストタイプとタクソノミーが独自の子サイトマップを取得するかについて、若干より細かい制御ができます。最近、80,000個のWooCommerceプロダクトを持つクライアントサイトでは、Rank Mathのデフォルトのセグメント化はYoastのものより整理されていました。 does the same, with slightly more granular control over which post types and taxonomies get their own child sitemaps. On a recent client site with 80,000 WooCommerce products, Rank Math's segmentation out of the box was cleaner than Yoast's.
  3. WP-CLIでのカスタム生成は、サイトに異常なコンテンツタイプがある場合、またはプラグインで生成されたサイトマップの生成が遅すぎる場合に使用します。データベースに直接クエリし、10,000のチャンク単位で結果をページネートし、XMLをディスクに書き込み、最後にインデックスファイルを書き込むスクリプトを書いてきました。200,000個のURLで30秒以内に実行されます。重要なのは、Googlebotが半分書き込まれたファイルにヒットすることがないよう、テンポラリファイルに書き込んでアトミックに移動させることです。 is what I reach for when the site has unusual content types or the plugin-generated sitemaps are too slow to generate. I've written scripts that query the database directly, paginate results in chunks of 10,000, write the XML to disk, and then write the index file last. Runs in under 30 seconds for 200,000 URLs. The key is writing to a temp file and atomically moving it into place so Googlebot never hits a half-written file.

WordPress以外のスタックの場合、Screaming Frog SEO Spiderはサイトをクロールしてサイトマップインデックスを生成できますが、本番環境のサイトマップジェネレータとしてではなく、検証ツールとしてより優れています。本番環境では、クローラーからではなく、データソースからサイトマップを生成してください。クローラーは見落とします。Screaming Frog SEO Spider can crawl your site and generate a sitemap index for you, though it's better as a validation tool than a production sitemap generator. For production, generate sitemaps from your data source, not from a crawler. Crawlers miss things.

Search Consoleで送信および検証する

Google Search Consoleに移動し、Sitemapsレポートを開いて、インデックスファイルURLを送信します。1つのURL。それだけです。Google Search Console, open the Sitemaps report, and submit your index file URL. One URL. That's it.

送信後、24~48時間待ってから、2つのことを確認します:

  • 送信済みと検出済み。「検出されたURL」の数は、実際のURLカウントに向かって増加しているはずです。奇妙に早くプラトーに達した場合、クロール予算の問題または不正なフォーマットの子サイトマップがある可能性があります。 The "Discovered URLs" count should be climbing toward your actual URL count. If it plateaus weirdly early, you likely have a crawl budget issue or a malformed child sitemap.
  • 子サイトマップの個別ステータス。Search Consoleでは各子サイトマップとそのステータスが表示されます。1つの子サイトマップがエラーを返している場合、他のファイルに手を加えることなくそれを特定できます。これがインデックス構造の過小評価されている利点です。 Search Console will show you each child sitemap and its status. If one child is returning an error, you can isolate it without touching the others. This is the underrated advantage of the index structure.

Bing Webmaster Toolsも同じ方法です。インデックスファイルを送信してください。子ファイルではなく。2分で済みます。

常に目にする一般的なミス

Seahawkは代理店向けのサイト監査をかなり定期的に実施しています。同じサイトマップエラーが何度も繰り返し出てきます。

サイトマップに含まれるnoindexのURL。URLがnoindexメタタグまたはX-Robotsヘッダーを持っている場合、サイトマップに含めるべきではありません。絶対です。サイトマップはクロールとインデックスへの推奨です。noindexされたURLを含めることはクロールバジェットを無駄にし、シグナルを混乱させます。本格的なサイト公開の前に、Screaming FrogでサイトマップURLに対して素早くクロール実行を行い、noindexレスポンスでフィルタリングします。 If a URL has a noindex meta tag or X-Robots header, it should not be in your sitemap. Full stop. A sitemap is a recommendation to crawl and index. Including noindexed URLs wastes crawl budget and confuses the signal. I run a quick Screaming Frog crawl against the sitemap URLs and filter for noindex responses before any major site launch.

サイトマップに含まれるブロックされたURL。noindexより悪い例:robots.txtでdisallowされているのにサイトマップにリストされているURL。Googlebotは矛盾を認識します。ペナルティを与えることはありませんが、ずさんであり時間の無駄です。 Even worse than noindex: URLs that are disallowed in robots.txt but still listed in the sitemap. Googlebot can see the contradiction. It won't penalise you for it, but it's sloppy and it wastes time.

新しい子サイトマップを追加した後、インデックスファイルを更新しない。これは明白に思えますが、カスタム実装をつまずかせます。新しいコンテンツタイプを追加し、新しい子サイトマップファイルを生成し、インデックスに<sitemap>エントリを追加するのを忘れます。子ファイルはディスク上に存在しますが、それを指すものはありません。これが気付かれないまま数ヶ月間存在していることを見たことがあります。 This sounds obvious but it trips up custom implementations. You add a new content type, generate a new child sitemap file, and forget to add the <sitemap> entry to the index. The child file exists on disk but nothing points to it. I've seen this sit unnoticed for months.

インデックスではなく、子サイトマップを個別にSearch Consoleに送信する。12個の子サイトマップがある場合、すべて12個をSearch Consoleに個別に送信すれば、組織的な利点を失っています。インデックスを送信してください。カスケード的に処理させてください。 If you have 12 child sitemaps and you submit all 12 to Search Console separately, you've lost the organisational benefit. Submit the index. Let it cascade.

クロールバジェット:より大きな全体像

サイトマップインデックスファイルはクロールバジェット管理に直結しています。このスケールで操作している場合、クロールバジェットに関するGoogleのドキュメンテーションは一読の価値があります。簡潔に言うと:Googlebotはサイトに1日あたり費やす時間が限られており、適切に構造化されたサイトマップインデックスはその時間を優先度の高いコンテンツに優先的に費やすのに役立ちます。Google's documentation on crawl budget is worth reading if you're operating at this scale. The short version: Googlebot has a finite amount of time it'll spend on your site per day, and a well-structured sitemap index helps it spend that time on your highest-priority content first.

大規模サイトでは、新しく更新されたコンテンツを専用の子サイトマップに分けています。これまで実装した例の中には、過去30日間に変更されたURLのみを含むsitemap-recent.xmlを使い、1時間ごとに更新するものがあります。Googlebotはこれに対して積極的に再クロールします。古い履歴サイトマップファイルはクロール頻度が低くなりますが、そのコンテンツは変更されないので問題ありません。sitemap-recent.xml that only contains URLs modified in the last 30 days, refreshed hourly. Googlebot recrawls that one aggressively. The older historical sitemap files get crawled less frequently, which is fine because that content isn't changing.

これはトリックではありません。クロールシグナルをコンテンツの現実に合わせているだけです。

FAQ

サイトマップインデックスファイルには何個の子サイトマップを含められますか?

プロトコルでは、単一のインデックスファイルに最大50,000個の子サイトマップを含めることができます。実際のところ、その数に近づいているなら数億個のURLを扱っており、ほとんどのサイトが直面しない問題に対処していることになります。大多数の大規模サイトの場合、子サイトマップは5~50個の間のどこかになります。

サイトマップファイルをgzipで圧縮する必要がありますか?

する必要はありませんが、大容量ファイルの場合は価値があります。50MBのサイトマップはgzipで約3~5MBに圧縮されます。Googlebotは設定なしで.xml.gzファイルを受け入れます。ほとんどの現代的なWebサーバーはサーバーレベルでgzip圧縮を有効にすれば、これを透過的に処理します。ディスクに生成される静的ファイルサイトマップの場合、gzipで事前圧縮して.xml.gzを直接配信しています。need to, but it's worth doing for large files. A 50MB sitemap compresses down to roughly 3-5MB with gzip. Googlebot accepts .xml.gz files without any configuration. Most modern web servers will handle this transparently if you enable gzip compression at the server level. For static-file sitemaps generated to disk, I pre-compress with gzip and serve the .xml.gz directly.

イメージサイトマップやビデオサイトマップをインデックスに含めるべきですか?

はい。イメージサイトマップ拡張またはビデオサイトマップを使用している場合、同じインデックスファイル内の子サイトマップとして含めることができます。標準的なURLサイトマップにイメージデータを混在させるのではなく、専用の子ファイルに保つでください。ファイルサイズが小さくなり、メディアライブラリが更新されたときにイメージサイトマップだけを再生成するのが容易になります。

子サイトマップが404を返した場合はどうなりますか?

Search Consoleはサイトマップレポートでそのチャイルドをエラー状態としてフラグを立てます。Googlebotはインデックス内の他のチャイルドサイトマップを処理し続けます。インデックス全体は無効化されませんが、404されたチャイルドにのみリストされているURLはサイトマップを通じて発見されません。すぐに修正してください。エラーは修正後も数週間Search Consoleのレポートに残りますが、これは迷惑なだけで無害です。

小規模サイトでサイトマップインデックスを使用できますか?

技術的にはそうですが、理由がありません。追加の複雑さは10,000 URL未満では価値がありません。単一のsitemap.xmlの方がメンテナンスが簡単で、デバッグが簡単で、同じ仕事を正確に行います。必要になったときにインデックスファイルを使用してください。必要になる前に使用してはいけません。

---

50,000 URLの制限は毎回人々を驚かせます。通常は製品ローンチ直前のような最悪のタイミングです。インデックス構造を一度正しく設定すれば、サイトが成長しても二度と考える必要がありません。それは1時間のセットアップの価値があります。

< BACK