Cloud Spanner использует вторичный индекс, когда он не должен - PullRequest
0 голосов
/ 03 января 2019

Существующий запрос, который быстро выполнялся с использованием первичного ключа, значительно замедлился (10 мс -> 8 с) без уведомления, поскольку вторичный индекс, созданный для другого варианта использования, теперь используется автоматически.

«Объяснение» Cloud-Spanner-Web-Query говорит мне, что используется вторичный индекс. Если я изменю порядок (только для целей тестирования) или предоставлю FORCE_INDEX, запрос снова будет быстрым.

Я могу «исправить» эту проблему с помощью FORCE_INDEX = _BASE_TABLE , которая описана в документации по синтаксису запроса Cloud Spanner .

Мой вопрос: действительно ли я должен делать это для каждого запроса, чтобы избежать таких эффектов?

Это смешивает определение запроса с определением индекса, что не очень хорошо, ИМХО.

Таблица с первичным индексом:

CREATE TABLE change_history (
    userId INT64 NOT NULL,
    createdAtUnique INT64 NOT NULL,
    itemId STRING(512) NOT NULL,
    newValue FLOAT64 NOT NULL,
    oldValue FLOAT64 NOT NULL,
) PRIMARY KEY (userId, itemId, createdAtUnique DESC)

Вторичный индекс:

CREATE INDEX ch_userid_createdatunique_all ON change_history (
    userId,
    createdAtUnique
) STORING (
    newValue,
    oldValue
)

Оригинальный запрос:

SELECT * FROM change_history WHERE                         
    userId = 2563
    AND itemId = "215414"
    AND createdAtUnique >= 15385766670000000
    AND createdAtUnique <= 15465254670000000 ORDER BY createdAtUnique

Я ожидал, что запрос будет продолжать использовать первичный ключ, для которого он был разработан.

Но, добавив вторичный индекс, запрос начал использовать этот вместо первичного ключа.

1 Ответ

0 голосов
/ 04 января 2019

Оптимизатор запросов в этом случае решил выбрать индекс, потому что 1) он покрывает и 2) избегает сортировки в исходном плане, поскольку индекс содержит createdAtUnique в порядке возрастания сортировки, который является порядком сортировки, запрошенным в запрос. Однако, для вашего распространения данных это оказалось плохим выбором.

Как правило, для запросов, которые были настроены вручную для получения определенного плана, который, по вашему мнению, является оптимальным / хорошим, рекомендуется использовать в запросе подсказки force_index и join_type для защиты от редкого экземпляра. когда оптимизатор может выбрать другой план.

...