אינדקסים וחלוקה גיאוגרפית

ב-Spanner יש כמה סוגים של אינדקסים לשיפור הביצועים של השאילתות. חשוב מאוד לבחור את סוג האינדקס הנכון לסכימה ולדפוסי השאילתות, במיוחד במסדי נתונים שמשתמשים בחלוקה גיאוגרפית. בדף הזה מתוארים היתרונות של סוגים שונים של אינדקסים ושיטות מומלצות לבחירה ולשימוש באינדקסים של Spanner עם חלוקה גיאוגרפית.

סוגי אינדקסים

‫Spanner תומך באינדקסים גלובליים, מקומיים ומרוחקים. לכל סוג יש מאפייני ביצוע שונים ותרחישי שימוש שונים. במסדי נתונים עם חלוקה גיאוגרפית, חשוב להבין את סוגי האינדקסים האלה. בחירת האינדקס הנכון עוזרת לכם לבצע אופטימיזציה של סכימת מסד הנתונים והשאילתות, וכך לשפר באופן משמעותי את זמן האחזור של מסד הנתונים שמחולק לפי מיקום גיאוגרפי. במסדי נתונים שלא נעשה בהם שימוש בחלוקה לפי מיקום גיאוגרפי, פחות חשוב להבין את סוגי האינדקסים האלה כי כולם מאוחסנים במיקום ברירת המחדל ויש להם מאפייני ביצועים דומים.

אינדקסים גלובליים

אינדקס גלובלי הוא סוג האינדקס שמוגדר כברירת מחדל ב-Spanner. נתוני האינדקס מאוחסנים במחיצת ברירת המחדל, שיכול להיות שהיא לא ממוקמת באותו מקום עם נתוני הטבלה. יצירת אינדקסים גלובליים בטבלאות עם חלוקה גיאוגרפית עשויה להוביל לזמני אחזור גבוהים משמעותית של פעולות כתיבה שכוללות את העמודות באינדקס, במיוחד אם הסכמת הכתיבה של מחיצת ברירת המחדל של האינדקס רחוקה מהסכמת הכתיבה של שורות הטבלה שנכתבות. כדי לצמצם את זמני האחזור של קריאה באינדקסים גלובליים, אפשר להשתמש בעותקים לקריאה בלבד שנמצאים בקרבת מקום, לצד אזורים עם הסכמי שכירות לקריאה או קריאות של נתונים לא עדכניים.

מאפיינים של אינדקסים גלובליים:

  • הן מאיצות שאילתות שדורשות אחרת סריקה מלאה של הטבלה, ומבטיחות ייחודיות בכל שורות הטבלה, ללא קשר למיקום.
  • הם מתאימים לעמודות שנדרשים בהן ערכים ייחודיים במסד נתונים.
  • הם מאיצים שאילתות שמסננות או ממיינות לפי עמודות מאונדקסות.

דוגמה לאינדקס ייחודי גלובלי:

CREATE UNIQUE INDEX idx_customer_email ON customer(email);

אינדקסים מקומיים

אינדקס מקומי משולב בהיררכיית האב של הטבלה המאונדקסת. השמות והסוגים של עמודות המפתח הראשי צריכים להיות זהים לאלה של הטבלה המאונדקסת.

למדדים מקומיים יש את המאפיינים הבאים:

  • הם מאחסנים נתוני אינדקס באותה מחיצה שבה מאוחסנים הנתונים שמתווספים לאינדקס. זמן האחזור של הכתיבה תלוי ברוב הדרוש לכתיבה במיקום הספציפי, ולא ברוב הדרוש לכתיבה במיקום שמוגדר כברירת מחדל.

  • הם מספקים את זמן האחזור הקצר ביותר לשאילתות שמכוונות לקידומת מפתח ספציפית, כי גם האינדקס וגם נתוני הטבלה ממוקמים באותו מיקום.

כדי ליצור אינדקס מקומי, משלבים את האינדקס בטבלת ההורה. אם משתמשים בUNIQUEאינדקס מקומי, הייחודיות נאכפת רק בשורה מסוימת של רכיב אב, ולא בכל הטבלה.

הדוגמה הבאה מראה איך ליצור אינדקס מקומי בטבלה customer, שמשולבת בטבלת ההורה locations:

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;

כשמבצעים שאילתה על נתונים בעסקה עם הרשאות קריאה וכתיבה, צריך לציין בשאילתה את הקידומת של המפתח הראשי של הטבלה המאונדקסת. אחרת, יכול להיות שהשאילתה תדרוש סריקה מלאה של הטבלה. לדוגמה:

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;

למידע על אופטימיזציה שלא מחייבת לציין את המיקום, אפשר לעיין במאמר שימוש באינדקס גלובלי ייחודי עם אינדקס מקומי או מרוחק.

אינדקס מקומי שימושי גם כשטבלת המיקום מבוססת על ישויות ורוצים ליצור אינדקס של נתונים בתוך ישות מסוימת או ישות משנה מסוימת. לדוגמה:

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;

מדדים מרוחקים

אינדקס מרוחק משלב נתוני אינדקס בטבלה שלא נמצאת בהיררכיית השילוב של הטבלה המאונדקסת. הסוגים של המפתחות הראשיים צריכים להיות זהים לסוגים של עמודות האינדקס המתאימות, אבל השמות יכולים להיות שונים.

כשמשתמשים בחלוקה גיאוגרפית, אפשר לשלב אינדקס מרוחק רק בטבלת מיקומי המודעות ברמה הבסיסית שמנוהלת באופן אוטומטי. הטבלה הזו מכילה שורה אחת לכל מיקום במסד הנתונים.

למדדים מרחוק יש את המאפיינים הבאים:

  • הם שימושיים במיוחד כשמפתח ראשי של טבלה לא מתחיל בקידומת של מפתח מיקום, אבל רוצים למקם מחיצות של האינדקס במיקום גיאוגרפי משותף בהתאם למפתח המיקום.
  • הם תומכים רק באינדקס של עמודות בטבלת המיקום, ולא בעמודות בטבלאות צאצאים משולבות.

כדי להשתמש באינדקסים מרוחקים עם חלוקה גיאוגרפית, צריך ליצור את טבלת המיקום הבסיסית על ידי הגדרת האפשרות auto_managed_root_placement_table_name בהצהרת ה-DDL‏ ALTER DATABASE.

  1. משתמשים בפקודה ALTER DATABASE DDL כדי ליצור טבלת מיקומי מודעות ברמת הבסיס.

    GoogleSQL

    ALTER DATABASE DATABASE_NAME SET OPTIONS
      (auto_managed_root_placement_table_name="TABLE_NAME");
    

    מחליפים את מה שכתוב בשדות הבאים:

    • DATABASE_NAME: השם של מסד הנתונים.
    • TABLE_NAME: השם של הטבלה שרוצים ליצור. מומלץ להשתמש בשם root_placement_table.

    לדוגמה, הפקודה הבאה יוצרת טבלה בשם root_placement_table.

    ALTER DATABASE example_db SET OPTIONS
      (auto_managed_root_placement_table_name='root_placement_table');
    

    אחרי שיוצרים את טבלת המיקום הבסיסית, Spanner יוצר טבלה פנימית ומוסיף או מוחק שורות באופן אוטומטי כשיוצרים או מסירים מיקום. הדוגמה הבאה היא של טבלת מיקום שמוגדרת על ידי המערכת ונוצרת על ידי Spanner, שבה שם הטבלה לדוגמה מוגדר כ-root_placement_table. (אל תפעילו את הדוגמה הזו).

    // 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';
    

    מחליפים את מה שכתוב בשדות הבאים:

    • DATABASE_NAME: השם של מסד הנתונים.
    • TABLE_NAME: השם של הטבלה שרוצים ליצור.

    לדוגמה, כדי ליצור טבלה בשם root_placement_table שמשמשת כשורש של שילוב, מריצים את הפקודה הבאה:

    ALTER DATABASE example_db SET
      spanner.auto_managed_root_placement_table_name='root_placement_table';
    

    אחרי שיוצרים את טבלת המיקום הבסיסית, Spanner יוצר טבלה פנימית ומוסיף או מוחק שורות באופן אוטומטי כשיוצרים או מסירים מיקום. הדוגמה הבאה היא של טבלת מיקום שמוגדרת על ידי המערכת ונוצרת על ידי Spanner, שבה שם הטבלה לדוגמה מוגדר כ-root_placement_table. (אל תפעילו את הדוגמה הזו).

    // 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)
    );
    
  2. יוצרים אינדקס מרוחק שמשולב בטבלה 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;
    
  3. כשמבצעים שאילתה על נתונים בעסקת קריאה-כתיבה, צריך לציין את קידומת המפתח של האינדקס בפרדיקט של השאילתה, כדי שלא יהיה צורך בסריקה מלאה של הטבלה. לדוגמה:

    GoogleSQL

    -- Specify the location (the index key prefix) in query
    SELECT *
    FROM customer
    WHERE location= @location AND email= @email;
    

    מידע על אופטימיזציה שלא דורשת ציון של המיקום מופיע בקטע אינדקס גלובלי ייחודי עם אינדקס מקומי או מרוחק

    PostgreSQL

    -- Specify the location (the index key prefix) in query
    SELECT *
    FROM customer
    WHERE location= @location AND email= @email;
    

    מידע על אופטימיזציה שלא דורשת ציון של המיקום מופיע בקטע אינדקס גלובלי ייחודי עם אינדקס מקומי או מרוחק.

אופטימיזציות לאינדקסים גלובליים ייחודיים

כשמשתמשים באינדקס גלובלי ייחודי, יכול להיות ש-Spanner יפעיל שיפורים בחביון של שאילתות באמצעות אופטימיזציות מבוססות היוריסטיקה במקרים הבאים:

  • כשמשתמשים באינדקס גלובלי ייחודי עם אינדקס מקומי או מרוחק
  • כשמשתמשים באינדקס גלובלי ייחודי עם מפתחות ראשיים חלקיים

בקטעים הבאים מתוארים האופטימיזציות ש-Spanner עשוי להחיל בכל תרחיש לדוגמה.

מדד גלובלי ייחודי עם מדד מקומי או מרוחק

כדי לשפר את זמן האחזור של שאילתות מקומיות, יכול להיות ש-Spanner יתחיל אופטימיזציה מבוססת-היוריסטיקה כשאינדקס ייחודי גלובלי משולב עם אינדקס מקומי או מרוחק.

האופטימיזציה הזו מצמצמת את זמן האחזור של שאילתות בתוך אזור מסוים – גם כשלא מצוין המיקום של נתונים שמחולקים לפי מיקום גיאוגרפי – על ידי ניחוש שהמיקום זהה למיקום של הלקוח, ודילוג על מחיצת ברירת המחדל של האינדקס הגלובלי, או על ידי ביטול הצורך בסריקות של טבלה מלאה עם סינון. הגישה הזו מועילה במיוחד כשרוב הגישה של הלקוחות היא לנתונים שמאוחסנים באזור שלהם.

שימוש בתמהיל של סוגי אינדקסים שונים יכול לעזור אם הבעיה העיקרית היא השהיה בשאילתות בתוך האזור, ואפשר לסבול עלייה מסוימת בהשהיה בכתיבה. שילוב של סוגי אינדקסים שונים משפר גם את הביצועים של שאילתות בתוך אזור, גם כשלא מציינים את המיקום בשאילתה.

כדי לבצע את האופטימיזציה הזו, צריך ליצור אינדקס ייחודי גלובלי ואינדקס מקומי או מרוחק תואם באותה עמודה. הנתונים שנוספו לאינדקס צריכים להיות ייחודיים באופן גלובלי. מערכת Spanner תחיל את האופטימיזציה הזו על השאילתה אם התנאים הבאים מתקיימים:

  • אתם לא יודעים מה הקידומת של המפתח הראשי ולא מציינים את המיקום של הנתונים.
  • הבקשה שלכם מגיעה מאותו אזור שבו נמצאת קבוצת השרתים המובילה שמוגדרת כברירת מחדל למיקום הנתונים, שמכילה את רסיס האינדקס המקומי או המרוחק.

מערכת Spanner מיישמת את האופטימיזציה בדרכים הבאות:

  • אם האופטימיזציה מופעלת והשורה נמצאת במיקום המקומי: בהינתן האינדקס הגלובלי הייחודי, Spanner לא צריך לחפש מיקומים אחרים. לשאילתה יש זמן אחזור בתוך האזור.
  • אם החיפוש הראשוני של המיקום לא מחזיר שורה: זה מצביע על כך שזו לא שאילתה בתוך אזור. אם לא, המערכת תחזור להשתמש באינדקס הגלובלי.

בדוגמה הבאה נוצר אינדקס גלובלי ייחודי ואינדקס מקומי:

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;

בדוגמה הבאה נוצר אינדקס ייחודי גלובלי ואינדקס מרוחק:

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;

בהתבסס על האינדקסים מהדוגמה הקודמת, לשאילתה הבאה יש השהיה בתוך האזור:

GoogleSQL

SELECT *
FROM customer
WHERE email= @email;

PostgreSQL

SELECT *
FROM customer
WHERE email= @email;

אינדקס גלובלי ייחודי במפתחות ראשיים חלקיים

‫Spanner יכול להחיל אופטימיזציה שדומה לזו שמפורטת במאמר שימוש באינדקס גלובלי ייחודי עם אינדקס מקומי או מרוחק כשמשתמשים באינדקס גלובלי ייחודי במפתחות ראשיים חלקיים.

בדוגמה הבאה נוצרת טבלה customer interleaved בטבלת האב locations, ואז נוצר אינדקס גלובלי ייחודי בעמודה customerId.

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);

האופטימיזציה חלה על שאילתות כמו:

GoogleSQL

SELECT * FROM customer WHERE customerId= @customerId;

PostgreSQL

SELECT * FROM customer WHERE customerId= @customerId;

אם לא יוצרים את האינדקס הייחודי הגלובלי, יכול להיות שהשאילתה הזו תדרוש סריקה מלאה של הטבלה. אם אתם לא משתמשים באינדקס הגלובלי הייחודי, תצטרכו להוסיף את מסנן המיקום לשאילתה כדי להשיג זמן אחזור טוב של השאילתה:

GoogleSQL

SELECT * FROM customer WHERE location = @location AND customerId= @customerId;

PostgreSQL

SELECT * FROM customer WHERE location = @location AND customerId= @customerId;

הנחיות כלליות לבחירת סוג אינדקס לזמן אחזור אופטימלי

סוג האינדקס שתבחרו ישפיע ישירות על זמן האחזור של השאילתות. המיקום של נתוני האינדקס ביחס לנתוני הטבלה הוא גורם מרכזי בביצועים של עומסי עבודה עם חלוקה לפי מיקום גיאוגרפי.

בקטע הזה מוסבר איך לבחור בין אינדקסים גלובליים, מקומיים ומרוחקים.

מתי כדאי לבחור באינדקסים גלובליים

משתמשים באינדקסים גלובליים אם עומס העבודה יכול לסבול את זמן האחזור המשויך לקריאה ולכתיבה, או אם נדרשת ייחודיות גלובלית בעמודות עם אינדקס.

כשבוחרים אינדקסים גלובליים, כדאי להביא בחשבון את הנקודות הבאות:

  • המרחק בין הלקוח לבין המנהיג של קוורום הכתיבה שמוגדר כברירת מחדל, יחד עם זמן האחזור שמוגדר כברירת מחדל לקוורום, קובעים את העלייה בזמן האחזור של הכתיבה. ההשפעה הזו מוגבלת ספציפית לפעולות שכוללות עמודות עם אינדקס, כמו הוספת שורות או עדכונים בעמודות עם אינדקס.
  • הוספה של עותקים לקריאה בלבד או שימוש בהרשאות קריאה יכולים להפחית את זמן האחזור המוגבר של הקריאה:
    • הוספה של עותק לקריאה בלבד בקרבה גיאוגרפית יכולה להפחית את זמן האחזור של קריאה לא עדכנית.
    • הוספה של עותק לקריאה בלבד ושימוש באזורים עם הרשאת קריאה יכולים להפחית את זמן האחזור של קריאות חזקות. אם מוסיפים עותק משוכפל לקריאה בלבד בלי להשתמש באזור עם הרשאת קריאה, זמן האחזור של קריאות חזקות לא יקטן, אבל קצב העברת הנתונים של הקריאות יכול לגדול.
    • ‫Spanner תמיד מציג קריאות טרנזקציונליות פסימיות מהלידר. הוספת רפליקות למיקום ברירת המחדל לא עוזרת בקריאות פסימיות של נתוני עסקאות במיקומי ברירת המחדל.
  • אינדקסים גלובליים (כולל מפתחות וערכים מאוחסנים) ממוקמים במיקום ברירת המחדל, שלא מספק נתונים ברמת המיקום. מידע נוסף זמין במאמר בנושא מיקום הנתונים ב-Spanner.

מתי כדאי לבחור אינדקסים מקומיים ואינדקסים מרוחקים

כשבוחרים אינדקסים מקומיים ואינדקסים מרוחקים, כדאי להביא בחשבון את הנקודות הבאות:

  • אינדקסים מקומיים ומרוחקים מספקים ביצועי קריאה וכתיבה מקומיים למיקום, אבל הם לא שומרים על הייחודיות הגלובלית ועל מאפייני הסדר של עמודות אינדקס ייחודיות. במקום זאת, אינדקסים מקומיים ואינדקסים מרחוק מספקים סדר וייחודיות של עמודות באינדקס בתוך שורת האב שבה הן משולבות.
  • כשמשתמשים במדדים מקומיים או מרוחקים, צריך לכלול את מיקום המיקום בפרדיקט של השאילתה, אלא אם יש גם מדד גלובלי ייחודי שמאפשר ל-Spanner לנחש את מיקום המיקום המקומי. אחרת, תוכנית השאילתה והביצועים לא יהיו דטרמיניסטיים. יכול להיות ש-Spanner יבצע סריקה של טבלת הבסיס או פיזור ואיסוף מהאינדקס במיקומי מיקום שונים על סמך נתונים סטטיסטיים של שאילתות, מה שיגדיל את זמן האחזור.

מתי כדאי לבחור אינדקסים גלובליים ייחודיים עם אינדקסים מקומיים או מרוחקים

כשבוחרים שילוב של אינדקסים גלובליים ייחודיים עם אינדקסים מקומיים או מרוחקים, כדאי לשים לב לנקודות הבאות:

  • כשמיקום המודעה הספציפי לא ידוע, אפשר להשתמש בשילוב של מדדים גלובליים ייחודיים עם מדדים מקומיים או מרוחקים. הגישה הזו מתאימה במיוחד כשרוב השאילתות מגיעות משירותים שממוקמים גיאוגרפית באותו אזור שבו ממוקמים הנתונים המבוקשים.
  • כשכותבים אינדקסים גלובליים, זמן האחזור של פעולות הכתיבה כפוף לזמן האחזור הנוסף של קוורום הכתיבה שמוגדר כברירת מחדל.
  • באופטימיזציה שמבוססת על היוריסטיקה, השאילתות מוגשות על ידי רסיסי אינדקס מקומיים, וברוב המקרים יש השהיה בתוך האזור.

הנחיות מפורטות לבחירת אינדקס לעיצובים ספציפיים של סכימות

אסטרטגיית האינדקס האופטימלית תלויה במבנה המפתח הראשי של הטבלה ובדפוסי השאילתות של האפליקציה. בקטע הזה מוסבר איך לבחור את סוג האינדקס המתאים לשלושה עיצובים נפוצים של סכימות:

  • סכימות שמשתמשות בישות כמפתח הראשי
  • סכימות שמשתמשות במיקום כמפתח הראשי
  • סכימות שמשתמשות בערכים שקשורים למיקום כמפתח הראשי

עיצוב סכימה: ישות כמפתח ראשי

אם הסכימה שלכם משתמשת בישות כמפתח הראשי, צריך לבחור את אסטרטגיית האינדוקס בהתאם לשאלה אם המיקום מצוין בשאילתות או לא.

במקרים שבהם ישות כמו customerID היא המפתח הראשי ועמודה נפרדת שאינה מפתח כמו location היא מפתח המיקום, צריך לקבוע את אסטרטגיית יצירת האינדקסים לטבלת המיקום על סמך דפוסי השאילתות. (אל תשתמשו בישות כמפתח ראשי של טבלת המיקומים אם זמן האחזור של ההוספה הוא בעיה עבור הישויות).

אם רוצים ליצור אינדקס של נתונים תחת ישות מסוימת, כמו customerID, אז צריך להשתמש באינדקס מקומי. הנתונים עוברים אינדוקס ומיון בתוך הישות, אבל לא בין ישויות. לדוגמה, אם רוצים ליצור אינדקס של ההזמנות של כל לקוח לפי תאריך, אפשר ליצור אינדקס מקומי שמשולב עם customerID הזהות.

אם המיקום תמיד ידוע בשאילתות שלכם, אפשר להשתמש באחת מהאסטרטגיות הבאות:

  • אם המיקום ידוע באופן עקבי בשאילתות שלכם ולא נדרש לאכוף ייחודיות גלובלית, אתם יכולים להשתמש במדדים מרוחקים. האינדקסים האלה מספקים זמן אחזור בתוך האזור גם לפעולות קריאה וגם לפעולות כתיבה.

    אינדקסים מרוחקים תומכים רק באינדקס של עמודות בטבלת המיקום, ולא בעמודות בטבלאות משולבות. האינדקס המרוחק צריך להיות משולב מתחת לטבלת המיקום הראשית. האינדקס המרוחק מבצע אינדוקס של נתונים בכל השורות של מיקום המודעה.

במקרים שבהם המיקום לא תמיד ידוע בשאילתות, אפשר להשתמש באחת מהאסטרטגיות הבאות:

  • אם העמודה עם האינדקס היא ייחודית באופן גלובלי, צריך ליצור אינדקס ייחודי גלובלי כדי לאכוף את הייחודיות הזו.

    כדי להשיג קריאות חזקות עם השהיה נמוכה, צריך ליצור אינדקס מרוחק בנוסף לאינדקס גלובלי ייחודי.

    בשילוב הזה, יכול להיות שפעולות כתיבה יגרמו לזמן אחזור בין אזורים, בעוד ששאילתות עם מיקום ספציפי (עם WHERE location= @location) ייהנו מזמן אחזור בתוך האזור באמצעות האינדקס המרוחק. בשביל שאילתות בלי מיקום ספציפי, Spanner משתמש באופטימיזציה שמבוססת על היוריסטיקה. הוא מחפש קודם באופן מקומי. אם הנתונים לא נמצאים, המערכת חוזרת לאינדקס הגלובלי.

    אם אתם משתמשים באזורים עם הרשאת קריאה ויש לכם עותק משוכפל לקריאה בלבד של המחיצה שמוגדרת כברירת מחדל באותו אזור שבו נמצאים הנתונים, אין צורך באינדקס מרוחק כי האזורים עם הרשאת קריאה כבר מספקים זמן אחזור נמוך לקריאה חזקה של אינדקס גלובלי.

  • אם השאילתה לא מציינת מיקום והעמודות באינדקס לא ייחודיות באופן גלובלי, המערכת תיצור רק אינדקס גלובלי (לא ייחודי). הוספה של אינדקס מקומי או מרוחק לא משפרת את זמן האחזור של הקריאה במקרה הזה, כי Spanner לא יכול לקבוע אם יש נתונים תואמים במיקום אחר, גם אם הוא מוצא נתונים במיקום המקומי.

עיצוב סכימה: מיקום כמפתח ראשי

כשעמודה location משמשת גם כמפתח ראשי וגם כמפתח מיקום, בחירת האינדקס מושפעת משיקולים של השהיה חוצה ומכך שהשאילתות תמיד מציינות את המיקום.

  • אם אין לכם בעיה עם זמן אחזור בין אזורים, או שאתם צריכים ייחודיות גלובלית, אתם יכולים להשתמש באינדקסים גלובליים.
  • אם אתם מודאגים לגבי זמן האחזור בין אזורים, השאילתות שלכם תמיד כוללות את המיקום, ואתם לא צריכים ש-Spanner יאכוף ייחודיות גלובלית, אתם יכולים להשתמש רק באינדקסים מקומיים. כך מובטח זמן אחזור מקומי גם לקריאה וגם לכתיבה.
  • אם השהיית השאילתות בין אזורים היא בעיה, אבל השהיית הכתיבה בין אזורים מקובלת, והמיקום לא תמיד ידוע, אפשר להשתמש באסטרטגיות הבאות:

    תנאי המלצה
    שאילתה לפי מפתח ראשי חלקי שהוא ייחודי באופן גלובלי

    יוצרים אינדקס גלובלי ייחודי כדי לאכוף ייחודיות. אין צורך באינדקס מקומי כי המפתח הראשי מבצע פונקציה דומה. האופטימיזציה על סמך היוריסטיקה חלה. קודם, מערכת Spanner בודקת את המפתח הראשי המלא עם המיקום המקומי לפני שהיא חוזרת לאינדקס הגלובלי.

    לדוגמה, ראו אינדקס ייחודי גלובלי במפתחות ראשיים חלקיים.

    שליחת שאילתה לפי עמודה ייחודית גלובלית שאינה מפתח

    יוצרים אינדקס גלובלי ייחודי כדי לאכוף ייחודיות.

    במקרה של השהיה בתוך אזור, יכולים להיות התרחישים הבאים:

    • יוצרים אינדקס מקומי באותה עמודה שבה נמצא האינדקס הגלובלי. האופטימיזציה מבוססת-היוריסטיקה חלה. השילוב של אינדקסים גלובליים ומקומיים מספק חביון נמוך לשאילתות חזקות ושאילתות לא עדכניות בתוך האזור, בעוד שלפעולות כתיבה ולשאילתות ולפעולות כתיבה חוצות-אזורים יש חביון חוצה-אזורים.
    • אם יש העתק לקריאה וכתיבה או העתק לקריאה בלבד של מחיצת ברירת המחדל באותו אזור שבו נמצאים הנתונים:
      • אם אתם צריכים חביון תוך-אזורי רק לקריאות לא עדכניות, ולא לקריאות חזקות, אתם לא צריכים אינדקס מקומי. העתק מקומי מספק זמן אחזור בתוך האזור.
      • אם אתם צריכים השהיה תוך-אזורית לקריאות חזקות, אתם יכולים ליצור אינדקס מקומי באותה עמודה כמו האינדקס הגלובלי, או להשתמש באזורים של הרשאות קריאה. אזורי חכירה לקריאה מספקים זמן אחזור קצר לקריאה חזקה, אבל זמן האחזור לכתיבה ארוך יותר.
    העמודה שנוספה לאינדקס לא ייחודית באופן גלובלי יצירה של אינדקס גלובלי בלבד. אינדקס מקומי לא משפר את זמן האחזור של קריאה, כי יכול להיות ש-Spanner יצטרך לבדוק את כל המיקומים.

אם אף אחד משלושת התרחישים האלה לא רלוונטי לתרחיש השימוש שלכם, כנראה שתצטרכו לוותר על הפשטות של האפליקציה או על זמן האחזור של הכתיבה, ולספק את המיקום באופן עקבי.

אם המפתח הראשי של הטבלה מבוסס על ערכים שקשורים למיקום, אבל הוא לא עמודת המפתח של מיקום המודעה (לדוגמה, אם משתמשים ב-country כמפתח הראשי כשמספר מיקומי המודעות קטן ממספר המדינות), אפשר להשתמש באינדקס גלובלי או באינדקס מקומי (שמשולב מתחת לעמודה country). עם זאת, לא ניתן להשתמש באינדקסים מרוחקים בטבלאות שמשולבות בטבלה מסוג מיקום כזה.

האופטימיזציה שמבוססת על היוריסטיקה לא נתמכת במקרה הזה עבור אינדקסים מקומיים. לכן, השהייה מקומית תושג רק אם השאילתה תציין במפורש את הקידומת של המפתח הראשי.