Spanner bietet verschiedene Arten von Indexen zur Verbesserung der Abfrageleistung. Die Auswahl des richtigen Indextyps für Ihr Schema und Ihre Abfragemuster ist entscheidend, insbesondere für Datenbanken, die Geo-Partitionierung verwenden. Auf dieser Seite werden die Vorteile verschiedener Indextypen und Best Practices für die Auswahl und Verwendung von Spanner-Indizes mit Geo-Partitionierung beschrieben.
Indexarten
Spanner unterstützt globale, lokale und Remote-Indexe. Jeder Typ hat unterschiedliche Leistungsmerkmale und Anwendungsfälle. Bei geografisch partitionierten Datenbanken ist es wichtig, diese Indextypen zu verstehen. Wenn Sie den richtigen Index auswählen, können Sie Ihr Datenbankschema und Ihre Abfragen optimieren. Das kann die Latenz Ihrer geopartitionierten Datenbank erheblich verbessern. Bei Datenbanken, die keine geografische Partitionierung verwenden, ist es weniger wichtig, diese Indextypen zu verstehen, da sie alle in der Standardplatzierung gespeichert sind und ähnliche Leistungsmerkmale aufweisen.
Globale Indexe
Ein globaler Index ist der Standardindextyp in Spanner. Die Indexdaten werden in der Standardpartition gespeichert, die sich möglicherweise nicht am selben Ort wie die Tabellendaten befindet. Das Erstellen globaler Indexe für geografisch partitionierte Tabellen kann zu deutlich höheren Schreiblatenzen für Schreibvorgänge führen, die die indexierten Spalten betreffen, insbesondere wenn das standardmäßige Schreibquorum für die Partition für den Index weit vom Schreibquorum der Tabellenzeilen entfernt ist, in die geschrieben wird. Sie können die Leselatenzen globaler Indexe verringern, indem Sie neben Read-Lease-Regionen oder veralteten Lesevorgängen auch schreibgeschützte Replikate in der Nähe verwenden.
Globale Indexe haben die folgenden Merkmale:
- Sie beschleunigen Abfragen, für die ansonsten ein vollständiger Tabellenscan erforderlich wäre, und erzwingen die Eindeutigkeit über alle Tabellenzeilen hinweg, unabhängig vom Standort.
- Sie eignen sich für Spalten, die in einer Datenbank eindeutige Werte erfordern.
- Sie beschleunigen Abfragen, die nach indexierten Spalten filtern oder sortieren.
Im Folgenden finden Sie ein Beispiel für einen global eindeutigen Index:
CREATE UNIQUE INDEX idx_customer_email ON customer(email);
Lokale Indexe
Ein lokaler Index ist in der übergeordneten Hierarchie der indexierten Tabelle verschränkt. Die Namen und Typen der Primärschlüsselspalten müssen mit der indexierten Tabelle übereinstimmen.
Lokale Indexe haben die folgenden Eigenschaften:
Sie speichern Indexdaten in derselben Partition wie die indexierten Daten. Die Schreiblatenz unterliegt dem Schreibquorum des jeweiligen Placements und nicht dem Standard-Schreibquorum des Placements.
Sie bieten die niedrigste Latenz für Abfragen, die auf ein bestimmtes Schlüsselpräfix ausgerichtet sind, da sowohl der Index als auch die Tabellendaten am selben Ort gespeichert sind.
Wenn Sie einen lokalen Index erstellen möchten, verschränken Sie den Index in der übergeordneten Tabelle. Wenn Sie einen UNIQUE-Lokalindex verwenden, wird die Eindeutigkeit nur innerhalb einer bestimmten übergeordneten Zeile und nicht in der gesamten Tabelle erzwungen.
Im Folgenden sehen Sie ein Beispiel für das Erstellen eines lokalen Index für die Tabelle customer, die in der übergeordneten Tabelle locations verschränkt ist:
GoogleSQL
-- Create locations placement table
CREATE TABLE locations (
location STRING(MAX) NOT NULL PLACEMENT KEY,
) PRIMARY KEY(location);
-- Create customer table interleaved in the locations table
CREATE TABLE customer (
location STRING(MAX) NOT NULL,
customerId INT64 NOT NULL,
email STRING(MAX),
webcookie STRING(64),
) PRIMARY KEY(location, customerId), INTERLEAVE IN PARENT locations;
-- Create a local index on the interleaved customer table
CREATE INDEX idx_customer_email_local ON customer(location, email),
INTERLEAVE IN locations;
PostgreSQL
-- Create locations placement table
CREATE TABLE locations (
location varchar NOT NULL PLACEMENT KEY PRIMARY KEY
);
-- Create customer table interleaved in the locations table
CREATE TABLE customer (
location varchar NOT NULL,
customerId BIGINT NOT NULL,
email varchar(1024),
webcookie varchar(64),
PRIMARY KEY(location, customerId)
) INTERLEAVE IN PARENT locations;
-- Create a local index on the interleaved customer table
CREATE INDEX idx_customer_email_local ON customer(location, email)
INTERLEAVE IN locations;
Wenn Sie Daten in einer Lese-/Schreibtransaktion abfragen, müssen Sie das Primärschlüsselpräfix der indexierten Tabelle in der Abfrage angeben. Andernfalls ist für die Abfrage möglicherweise ein vollständiger Tabellenscan erforderlich. Beispiel:
GoogleSQL
-- The location (the index key prefix) must be specified
SELECT *
FROM customer
WHERE location= @location AND email= @email;
PostgreSQL
-- The location (the index key prefix) must be specified
SELECT *
FROM customer
WHERE location= @location AND email= @email;
Informationen zur Optimierung, bei der Sie den Standort nicht angeben müssen, finden Sie unter Global eindeutigen Index mit lokalem oder Remote-Index verwenden.
Ein lokaler Index ist auch nützlich, wenn die Placement-Tabelle auf Entitäten basiert und Sie Daten innerhalb einer bestimmten Entität oder untergeordneten Entität indexieren möchten. Beispiel:
GoogleSQL
-- Create entity based customer placement table
CREATE TABLE customer (
customerId INT64 NOT NULL,
email STRING(MAX),
webcookie STRING(64),
location STRING(MAX) NOT NULL PLACEMENT KEY
) PRIMARY KEY(customerId);
-- Create customerOrders child table
CREATE TABLE customerOrders (
customerId INT64 NOT NULL,
orderId INT64 NOT NULL,
orderName STRING(MAX) NOT NULL
) PRIMARY KEY(customerId, orderId), INTERLEAVE IN PARENT customer;
-- Create a local index on the interleaved child table
CREATE INDEX idx_order_local ON customerOrders(customerId, orderName),
INTERLEAVE IN customer;
PostgreSQL
-- Create entity based customer placement table
CREATE TABLE customer (
customerId BIGINT NOT NULL PRIMARY KEY,
email varchar(1024),
webcookie varchar(64),
location varchar NOT NULL PLACEMENT KEY
);
-- Create customerOrders child table
CREATE TABLE customerOrders (
customerId BIGINT NOT NULL,
orderId BIGINT NOT NULL,
orderName varchar(1024) NOT NULL,
PRIMARY KEY(customerId, orderId)
) INTERLEAVE IN PARENT customer;
-- Create a local index on the interleaved child table
CREATE INDEX idx_order_local ON customerOrders(customerId, orderName)
INTERLEAVE IN customer;
Remote-Indexe
Bei einem Remote-Index werden Indexdaten unter einer Tabelle verschränkt, die kein Ancestor in der Verschachtelungshierarchie der indexierten Tabelle ist. Die Primärschlüsseltypen müssen mit den Typen der entsprechenden Indexspalten übereinstimmen, die Namen können jedoch unterschiedlich sein.
Mit der geografischen Partitionierung können Sie einen Remote-Index nur in die automatisch verwaltete Stammplatzierungstabelle einfügen. Diese Tabelle enthält eine Zeile für jede Platzierung in Ihrer Datenbank.
Remote-Indizes haben die folgenden Eigenschaften:
- Sie sind besonders nützlich, wenn der Primärschlüssel der Tabelle nicht mit einem Placementschlüssel versehen ist, Sie aber Partitionen des Index geografisch entsprechend dem Placementschlüssel anordnen möchten.
- Sie unterstützen nur das Indexieren von Spalten in der Placement-Tabelle, nicht von Spalten in den verschachtelten untergeordneten Tabellen.
Wenn Sie Remote-Indizes mit geografischer Partitionierung verwenden möchten, erstellen Sie die Stammplatzierungstabelle, indem Sie die Option auto_managed_root_placement_table_name in der DDL-Anweisung ALTER
DATABASE festlegen.
Verwenden Sie die
ALTER DATABASE DDL-Anweisung, um eine Tabelle für die Platzierung auf Stammebene zu erstellen.GoogleSQL
ALTER DATABASE DATABASE_NAME SET OPTIONS (auto_managed_root_placement_table_name="TABLE_NAME");Ersetzen Sie Folgendes:
- DATABASE_NAME: Der Name Ihrer Datenbank.
- TABLE_NAME: Der Name der zu erstellenden Tabelle. Wir empfehlen, den Namen
root_placement_tablezu verwenden.
Mit dem folgenden Befehl wird beispielsweise eine Tabelle mit dem Namen
root_placement_tableerstellt.ALTER DATABASE example_db SET OPTIONS (auto_managed_root_placement_table_name='root_placement_table');Nachdem Sie die Stammplatzierungstabelle erstellt haben, erstellt Spanner eine interne Tabelle und fügt automatisch Zeilen ein und löscht sie, wenn Sie eine Platzierung erstellen oder löschen. Im Folgenden sehen Sie ein Beispiel für eine von Spanner erstellte systemdefinierte Placement-Tabelle. Der Beispieltabellenname ist auf
root_placement_tablefestgelegt. (Führen Sie dieses Beispiel nicht aus.)// Automatically generated after you run the previous example. // Don't put this in your schema explicitly. CREATE TABLE root_placement_table ( location STRING(MAX) NOT NULL PLACEMENT KEY ) PRIMARY KEY(location);
PostgreSQL
ALTER DATABASE DATABASE_NAME SET spanner.auto_managed_root_placement_table_name='TABLE_NAME';Ersetzen Sie Folgendes:
- DATABASE_NAME: Der Name Ihrer Datenbank.
- TABLE_NAME: Der Name der zu erstellenden Tabelle.
Wenn Sie beispielsweise eine
root_placement_table-Tabelle erstellen möchten, die als Interleave-Stamm verwendet wird, führen Sie Folgendes aus:ALTER DATABASE example_db SET spanner.auto_managed_root_placement_table_name='root_placement_table';Nachdem Sie die Stammplatzierungstabelle erstellt haben, erstellt Spanner eine interne Tabelle und fügt automatisch Zeilen ein und löscht sie, wenn Sie eine Platzierung erstellen oder löschen. Im Folgenden sehen Sie ein Beispiel für eine von Spanner erstellte systemdefinierte Placement-Tabelle. Der Beispieltabellenname ist auf
root_placement_tablefestgelegt. (Führen Sie dieses Beispiel nicht aus.)// Automatically generated after you run the previous example. // Don't put this in your schema explicitly. CREATE TABLE root_placement_table ( location varchar NOT NULL PLACEMENT KEY, PRIMARY KEY (location) );
Erstellen Sie einen verschränkten Remote-Index unter der automatisch verwalteten Tabelle
root_placement_table.GoogleSQL
-- Create a customer table with a primary key that is not the location CREATE TABLE customer ( customerId INT64 NOT NULL , email STRING(MAX), webcookie STRING(64), location STRING(MAX) NOT NULL PLACEMENT KEY, ) PRIMARY KEY(customerId); -- Create a remote index on the customer table CREATE INDEX idx_customer_email_remote ON customer(location, email), INTERLEAVE IN root_placement_table;PostgreSQL
-- Create a customer table with a primary key that is not the location CREATE TABLE customer ( customerId BIGINT NOT NULL PRIMARY KEY, email varchar(1024), webcookie varchar(64), location varchar NOT NULL PLACEMENT KEY ); -- Creates a remote index on the customer table CREATE INDEX idx_customer_email_remote ON customer(location, email) INTERLEAVE IN root_placement_table;Wenn Sie Daten in einer Lese-/Schreibtransaktion abfragen, geben Sie das Schlüsselpräfix des Index im Abfrageprädikat an, damit kein vollständiger Tabellenscan erforderlich ist. Beispiel:
GoogleSQL
-- Specify the location (the index key prefix) in query SELECT * FROM customer WHERE location= @location AND email= @email;Informationen zur Optimierung, bei der Sie den Standort nicht angeben müssen, finden Sie im Abschnitt Global eindeutiger Index mit lokalem oder Remote-Index.
PostgreSQL
-- Specify the location (the index key prefix) in query SELECT * FROM customer WHERE location= @location AND email= @email;Informationen zur Optimierung, bei der Sie den Standort nicht angeben müssen, finden Sie im Abschnitt Global eindeutiger Index mit lokalem oder Remote-Index.
Optimierungen für global eindeutige Indexe
Wenn Sie einen global eindeutigen Index verwenden, kann Spanner in den folgenden Anwendungsfällen die Abfragelatenz durch heuristische Optimierungen verbessern:
- Globale eindeutige Indexe mit lokalen oder Remote-Indexen verwenden
- Globale eindeutige Indexe mit partiellen Primärschlüsseln verwenden
In den folgenden Abschnitten wird beschrieben, wie Spanner in den einzelnen Anwendungsfällen Optimierungen anwenden kann.
Global eindeutiger Index mit einem lokalen oder Remote-Index
Zur Verbesserung der Latenz lokaler Abfragen kann Spanner eine heuristikbasierte Optimierung starten, wenn ein global eindeutiger Index mit einem lokalen oder Remote-Index kombiniert wird.
Diese Optimierung minimiert die Latenz für regioneninterne Abfragen – auch wenn der Speicherort der geografisch partitionierten Daten nicht angegeben ist. Dabei wird davon ausgegangen, dass der Speicherort derselbe ist wie der des Clients. Die Standardpartition des globalen Index wird umgangen oder gefilterte vollständige Tabellenscans werden überflüssig. Ein solcher Ansatz ist besonders vorteilhaft, wenn Kunden hauptsächlich auf Daten zugreifen, die in ihrer eigenen Region gespeichert sind.
Die Verwendung einer Mischung aus verschiedenen Indextypen ist hilfreich, wenn die Abfragelatenz innerhalb der Region das Hauptproblem ist und Sie eine gewisse erhöhte Schreiblatenz tolerieren können. Durch die Kombination verschiedener Indextypen wird auch die Leistung von regioneninternen Abfragen verbessert, selbst wenn Sie den Standort in Ihrer Abfrage nicht angeben.
Für diese Optimierung müssen Sie einen global eindeutigen Index und einen entsprechenden lokalen oder Remote-Index für dieselbe Spalte erstellen. Die indexierten Daten müssen global eindeutig sein. Spanner wendet diese Optimierung auf Ihre Abfrage an, wenn Folgendes zutrifft:
- Sie kennen das Präfix des Primärschlüssels nicht und geben den Speicherort der Daten nicht an.
- Ihre Anfrage stammt aus derselben Region wie der Standard-Leader der Datenplatzierung, der den lokalen oder Remote-Index-Shard enthält.
Spanner wendet die Optimierung auf folgende Weise an:
- Wenn die Optimierung ausgelöst wird und die Zeile im lokalen Placement gefunden wird: Aufgrund des global eindeutigen Index muss Spanner nicht an anderen Standorten suchen. Ihre Anfrage hat eine Latenz innerhalb der Region.
- Wenn bei der ersten Standortsuchen keine Zeile zurückgegeben wird: Das bedeutet, dass es sich nicht um eine regionsinterne Anfrage handelt. Spanner greift auf den globalen Index zurück.
Im folgenden Beispiel werden ein global eindeutiger Index und ein lokaler Index erstellt:
GoogleSQL
CREATE UNIQUE INDEX idx_customer_email ON customer(email);
CREATE INDEX idx_customer_email_local ON customer(location, email), INTERLEAVE IN locations;
PostgreSQL
CREATE UNIQUE INDEX idx_customer_email ON customer(email);
CREATE INDEX idx_customer_email_local ON customer(location, email) INTERLEAVE IN locations;
Im folgenden Beispiel werden ein global eindeutiger Index und ein Remote-Index erstellt:
GoogleSQL
CREATE UNIQUE INDEX idx_customer_email ON customer(email);
CREATE INDEX idx_customer_email_remote ON customer(location, email), INTERLEAVE IN root_placement_table;
PostgreSQL
CREATE UNIQUE INDEX idx_customer_email ON customer(email);
CREATE INDEX idx_customer_email_remote ON customer(location, email) INTERLEAVE IN root_placement_table;
Basierend auf den Indexen aus dem vorherigen Beispiel hat die folgende Beispielabfrage eine Latenz innerhalb der Region:
GoogleSQL
SELECT *
FROM customer
WHERE email= @email;
PostgreSQL
SELECT *
FROM customer
WHERE email= @email;
Global eindeutiger Index für partielle Primärschlüssel
Spanner kann eine Optimierung anwenden, die der in Globalen eindeutigen Index mit einem lokalen oder Remote-Index verwenden beschriebenen Optimierung ähnelt, wenn ein globaler eindeutiger Index für partielle Primärschlüssel verwendet wird.
Im folgenden Beispiel wird eine customer erstellt, die in die übergeordnete Tabelle locations eingefügt wird. Anschließend wird ein global eindeutiger Index für die Spalte customerId erstellt.
GoogleSQL
-- Create locations placement table
CREATE TABLE locations (
location STRING(MAX) NOT NULL PLACEMENT KEY,
) PRIMARY KEY(location);
-- Create customer table interleaved in the locations table
CREATE TABLE customer (
location STRING(MAX) NOT NULL,
customerId INT64 NOT NULL,
email STRING(MAX),
webcookie STRING(64),
) PRIMARY KEY(location, customerId), INTERLEAVE IN PARENT locations;
-- Create global unique index on customerId column
CREATE UNIQUE INDEX idx_customer_customerid ON customer(customerId);
PostgreSQL
-- Create locations placement table
CREATE TABLE locations (
location varchar NOT NULL PLACEMENT KEY PRIMARY KEY
);
-- Create customer table interleaved in the locations table
CREATE TABLE customer (
location varchar NOT NULL,
customerId BIGINT NOT NULL,
email varchar(1024),
webcookie varchar(64),
PRIMARY KEY(location, customerId)
) INTERLEAVE IN PARENT locations;
-- Create global unique index on customerId column
CREATE UNIQUE INDEX idx_customer_customerid ON customer(customerId);
Die Optimierung gilt für Abfragen wie die folgenden:
GoogleSQL
SELECT * FROM customer WHERE customerId= @customerId;
PostgreSQL
SELECT * FROM customer WHERE customerId= @customerId;
Wenn Sie den global eindeutigen Index nicht erstellen, ist für diese Abfrage möglicherweise ein vollständiger Tabellenscan erforderlich. Wenn Sie den global eindeutigen Index nicht verwenden, müssen Sie den Standortfilter in Ihre Abfrage einfügen, um eine gute Abfragelatenz zu erzielen:
GoogleSQL
SELECT * FROM customer WHERE location = @location AND customerId= @customerId;
PostgreSQL
SELECT * FROM customer WHERE location = @location AND customerId= @customerId;
Allgemeine Richtlinien für die Auswahl eines Indextyps für optimale Latenz
Der von Ihnen ausgewählte Indextyp wirkt sich direkt auf die Abfragelatenz aus. Der Speicherort von Indexdaten im Verhältnis zu Tabellendaten ist ein wichtiger Faktor für die Leistung von geografisch partitionierten Arbeitslasten.
In diesem Abschnitt wird beschrieben, wie Sie zwischen globalen, lokalen und Remote-Indexen wählen.
Wann sollten globale Indexe verwendet werden?
Verwenden Sie globale Indexe, wenn Ihre Arbeitslast die zugehörige Lese- und Schreiblatenz tolerieren kann oder wenn Sie eine erzwungene globale Eindeutigkeit für indexierte Spalten benötigen.
Berücksichtigen Sie bei der Auswahl globaler Indexe Folgendes:
- Die Entfernung zwischen dem Client und dem Leader des Standard-Schreibquorums bestimmt zusammen mit der Standardlatenz des Quorums die Erhöhung der Schreiblatenz. Dieser Effekt ist speziell auf Vorgänge mit indexierten Spalten beschränkt, z. B. das Einfügen von Zeilen oder das Aktualisieren von indexierten Spalten.
- Das Hinzufügen schreibgeschützter Replikate oder die Verwendung von Leseleases kann die erhöhte Leselatenz verringern:
- Wenn Sie ein schreibgeschütztes Replikat in geografischer Nähe hinzufügen, kann die Latenz bei Lesevorgängen veralteter Daten reduziert werden.
- Durch das Hinzufügen eines schreibgeschützten Replikats und die Verwendung von Regionen mit Lese-Lease kann die Latenz bei starken Lesevorgängen reduziert werden. Wenn Sie ein schreibgeschütztes Replikat hinzufügen, ohne eine Region mit Leselease zu verwenden, wird die Latenz für starke Lesevorgänge nicht reduziert, aber der Lesedurchsatz kann steigen.
- Spanner stellt pessimistische Transaktionslesevorgänge immer vom Leader bereit. Das Hinzufügen von Replikaten zum Standard-Placement hilft nicht bei pessimistischen transaktionalen Lesevorgängen von Daten in den Standard-Placements.
- Globale Indexe (einschließlich Schlüssel und gespeicherter Werte) werden am Standardspeicherort platziert, der keine Datenresidenz auf Placement-Ebene bietet. Weitere Informationen finden Sie in der Übersicht zum Datenstandort für Spanner.
Wann sollten lokale und wann Remote-Indizes verwendet werden?
Beachten Sie bei der Auswahl lokaler und Remote-Indizes Folgendes:
- Lokale und Remote-Indizes bieten eine platzierungsbezogene Lese- und Schreibleistung, beeinträchtigen jedoch die globalen Eindeutigkeits- und Sortierungseigenschaften von Spalten mit eindeutigen Indexen. Stattdessen sorgen lokale und Remote-Indexe für die Reihenfolge und Eindeutigkeit der indexierten Spalten innerhalb der übergeordneten Zeile, in die sie verschachtelt sind.
- Wenn Sie lokale oder Remote-Indexe verwenden, müssen Sie den Speicherort der Platzierung in das Abfrageprädikat einfügen, es sei denn, es gibt auch einen global eindeutigen Index, mit dem Spanner den lokalen Speicherort der Platzierung erraten kann. Andernfalls sind der Abfrageplan und die Leistung nicht deterministisch. Spanner führt möglicherweise einen Scan der Basistabelle oder einen Scatter-and-Gather-Vorgang aus dem Index über die Platzierungsorte hinweg auf Grundlage von Abfragestatistiken aus, was die Latenz erhöht.
Globale eindeutige Indexe mit lokalen oder Remote-Indexen verwenden
Beachten Sie Folgendes, wenn Sie eine Kombination aus global eindeutigen Indexen zusammen mit lokalen oder Remote-Indexen auswählen:
- Wenn der genaue Placement-Standort unbekannt ist, verwenden Sie eine Kombination aus global eindeutigen Indexen mit lokalen oder Remote-Indexen. Dieser Ansatz ist ideal, wenn die meisten Anfragen von Diensten stammen, die sich geografisch in derselben Region wie der Speicherort der angeforderten Daten befinden.
- Beim Schreiben globaler Indexe unterliegt die Schreiblatenz einer zusätzlichen Standardlatenz für das Schreibquorum.
- Bei der heuristischen Optimierung werden Anfragen von lokalen Index-Shards beantwortet. Die Latenz innerhalb der Region ist also meist gering.
Detaillierte Richtlinien für die Auswahl eines Index für bestimmte Schemadesigns
Die optimale Indexstrategie hängt von der Primärschlüsselstruktur Ihrer Tabelle und den Abfragemustern Ihrer Anwendung ab. In diesem Abschnitt finden Sie eine Anleitung zur Auswahl des geeigneten Indextyps für drei gängige Schemadesigns:
- Schemas, die eine Entität als Primärschlüssel verwenden
- Schemas, in denen der Standort als Primärschlüssel verwendet wird
- Schemas, in denen standortbezogene Werte als Primärschlüssel verwendet werden
Schemadesign: Entität als Primärschlüssel
Wenn in Ihrem Schema eine Entität als Primärschlüssel verwendet wird, wählen Sie Ihre Indexierungsstrategie danach aus, ob in Ihren Abfragen ein Ort angegeben ist.
Wenn eine Entität wie customerID der Primärschlüssel und eine separate Nicht-Schlüsselspalte wie location der Platzierungsschlüssel ist, legen Sie die Indexierungsstrategie für die Platzierungstabelle anhand Ihrer Abfragemuster fest. Verwenden Sie keine Entität als Primärschlüssel der Placement-Tabelle, wenn die Einfügungsverzögerung für die Entitäten ein Problem darstellt.
Wenn Sie Daten unter einer bestimmten Entität wie customerID indexieren möchten, verwenden Sie einen lokalen Index. Daten werden innerhalb der Einheit indexiert und sortiert, aber nicht über die Einheit hinweg. Wenn Sie beispielsweise die Bestellungen jedes Kunden nach Datum indexieren möchten, können Sie einen lokalen Index erstellen, der unter der Identität customerID verschachtelt ist.
Wenn der Standort in Ihren Anfragen immer bekannt ist, verwenden Sie eine der folgenden Strategien:
Wenn der Standort in Ihren Abfragen immer bekannt ist und die globale Eindeutigkeit nicht erzwungen werden muss, verwenden Sie Remote-Indexe. Diese Indexe bieten eine Latenz innerhalb der Region für Lese- und Schreibvorgänge.
Bei Remote-Indexen werden nur Spalten in der Placement-Tabelle indexiert, nicht in verschränkten Tabellen. Der Remote-Index muss in der Stamm-Placement-Tabelle verschränkt sein. Im Remote-Index werden Daten aus allen Placement-Zeilen für das Placement indexiert.
Wenn der Standort in Ihren Anfragen nicht immer bekannt ist, verwenden Sie eine der folgenden Strategien:
Wenn die indexierte Spalte global eindeutig ist, erstellen Sie einen global eindeutigen Index, um diese Eindeutigkeit zu erzwingen.
Wenn Sie Lesevorgänge mit geringer Latenz und Strong Consistency erreichen möchten, erstellen Sie zusätzlich zu einem global eindeutigen Index einen Remote-Index.
Bei dieser Kombination kann es bei Schreibvorgängen zu latenzbedingten Verzögerungen zwischen Regionen kommen, während Abfragen mit einem angegebenen Standort (mit
WHERE location= @location) von der Latenz innerhalb der Region profitieren, da der Remote-Index verwendet wird. Bei Abfragen ohne angegebenen Standort verwendet Spanner eine heuristische Optimierung, indem zuerst lokal gesucht wird. Wenn die Daten nicht gefunden werden, wird auf den globalen Index zurückgegriffen.Wenn Sie Read-Lease-Regionen verwenden und ein schreibgeschütztes Replikat der Standardpartition in derselben Region wie Ihre Daten haben, ist ein Remote-Index nicht erforderlich, da die Read-Lease-Regionen bereits eine geringe starke Leselatenz für Lesevorgänge eines globalen Index bieten.
Wenn in Ihrer Abfrage kein Standort angegeben ist und die indexierten Spalten nicht global eindeutig sind, erstellen Sie nur einen globalen (nicht eindeutigen) Index. Das Hinzufügen eines lokalen oder Remote-Index verbessert die Leselatenz in diesem Fall nicht, da Spanner nicht feststellen kann, ob es übereinstimmende Daten an einem anderen Speicherort gibt, selbst wenn Spanner Daten am lokalen Speicherort findet.
Schemadesign: „Location“ als Primärschlüssel
Wenn eine location-Spalte sowohl als Primärschlüssel als auch als Placement-Schlüssel dient, wird Ihre Indexauswahl durch latenzübergreifende Bedenken und die Frage beeinflusst, ob in Ihren Abfragen immer der Standort angegeben wird.
- Wenn die regionsübergreifende Latenz keine Rolle spielt oder Sie globale Eindeutigkeit benötigen, verwenden Sie globale Indexe.
- Wenn die regionsübergreifende Latenz ein Problem darstellt, Ihre Abfragen immer den Standort enthalten und Sie nicht möchten, dass Spanner die globale Eindeutigkeit erzwingt, verwenden Sie nur lokale Indexe. So wird die lokale Latenz sowohl für Lese- als auch für Schreibvorgänge gewährleistet.
Wenn die regionsübergreifende Abfragelatenz ein Problem darstellt, die regionsübergreifende Schreiblatenz akzeptabel ist und der Standort nicht immer bekannt ist, gelten die folgenden Strategien:
Bedingung Empfehlung Abfrage nach einem partiellen Primärschlüssel, der global eindeutig ist Erstellen Sie einen eindeutigen globalen Index, um die Eindeutigkeit zu erzwingen. Ein lokaler Index ist nicht erforderlich, da der Primärschlüssel eine ähnliche Funktion erfüllt. Die heuristikbasierte Optimierung wird angewendet. Zuerst vergleicht Spanner den vollständigen Primärschlüssel mit dem lokalen Standort, bevor auf den globalen Index zurückgegriffen wird.
Ein Beispiel finden Sie unter Global eindeutiger Index für teilweise Primärschlüssel.
Abfrage nach einer nicht schlüsselbasierten, global eindeutigen Spalte Erstellen Sie einen eindeutigen globalen Index, um die Eindeutigkeit zu erzwingen.
Für die Latenz innerhalb einer Region sind die folgenden Szenarien möglich:
- Erstellen Sie einen lokalen Index für dieselbe Spalte wie den globalen Index. Die heuristikbasierte Optimierung wird angewendet. Die Kombination aus globalen und lokalen Indexen sorgt für eine niedrige Latenz bei starken und veralteten Anfragen innerhalb der Region, während Schreibvorgänge und regionenübergreifende Anfragen und Schreibvorgänge eine regionenübergreifende Latenz aufweisen.
-
Wenn es ein Lese-/Schreib- oder schreibgeschütztes Replikat der Standardpartition in derselben Region wie Ihre Daten gibt, gilt Folgendes:
- Wenn Sie nur eine regionsinterne Latenz für veraltete Lesevorgänge, nicht aber für starke Lesevorgänge benötigen, ist kein lokaler Index erforderlich. Das lokale Replikat bietet eine Latenz innerhalb der Region.
- Wenn Sie eine Latenz innerhalb der Region für starke Lesevorgänge benötigen, können Sie einen lokalen Index für dieselbe Spalte wie den globalen Index erstellen oder Read-Lease-Regionen verwenden. Regionen mit Lesefreigabe bieten eine niedrige Latenz für starke Lesevorgänge, jedoch auf Kosten der Schreiblatenz.
Indexierte Spalte ist nicht global eindeutig Nur einen globalen Index erstellen. Ein lokaler Index verbessert die Leselatenz nicht, da Spanner möglicherweise alle Standorte prüfen muss.
Wenn diese drei Szenarien nicht auf Ihren Anwendungsfall zutreffen, müssen Sie wahrscheinlich die Einfachheit der Anwendung oder die Latenz in Kauf nehmen, indem Sie den Standort konsistent angeben.
Schemadesign: Standortbezogene Werte als Primärschlüssel
Wenn der Primärschlüssel Ihrer Tabelle auf standortbezogenen Werten basiert, aber nicht direkt die Spalte für den Placement-Schlüssel ist (z. B. wenn Sie country als Primärschlüssel verwenden, wenn Sie weniger Placements als Länder haben), können Sie entweder einen globalen Index oder einen lokalen Index (verschachtelt unter der Spalte country) verwenden. Remote-Indizes werden jedoch für keine Tabellen unterstützt, die in Tabellen dieses Typs verschachtelt sind.
Die heuristikbasierte Optimierung wird für lokale Indexe in diesem Szenario nicht unterstützt. Daher wird die lokale Latenz nur erreicht, wenn in Ihrer Abfrage der Primärschlüsselpräfix explizit angegeben ist.