[Документация Yandex Cloud](../../index.md) > [Yandex Managed Service for Sharded PostgreSQL](../index.md) > Вопросы и ответы > Распределенные запросы

# Распределенные запросы в Managed Service for Sharded PostgreSQL

* [Как Sharded PostgreSQL обрабатывает SQL-запросы?](#sql-queries-parcing)

* [Как выполнять транзакции с несколькими шардами?](#multi-shard-transactions)

* [Как принудительно указать, на каком шарде выполнить запрос?](#how-to-specify-shard)

* [Какие стратегии фиксации транзакций поддерживаются?](#commit-strategy)

* [Как работают справочные таблицы (reference tables)?](#reference-tables)

* [Как создать справочные таблицы (reference tables)?](#how-to-create-reference-table)

* [Поддерживает ли Sharded PostgreSQL распределенные последовательности (distributed sequences)?](#distributed-sequences)

* [Можно ли шардировать связанные таблицы по одному ключу?](#single-key-sharding-for-connected-tables)

* [Как выполняются запросы без явного ключа шардирования?](#queries-with-no-explicit-key)

#### Как Sharded PostgreSQL обрабатывает SQL-запросы? {#sql-queries-parcing}
Sharded PostgreSQL обрабатывает SQL-запросы в зависимости от их типа и контекста:

* Обычные запросы — Sharded PostgreSQL обрабатывает запрос, определяет таблицу, колонку и значение, к которому происходит обращение. Эти данные сопоставляются с заранее заданными правилами шардирования (например, по ключу или диапазону). На основе этих правил система определяет целевой шард, на который нужно отправить запрос.

* Запросы с настройками роутинга — на маршрутизацию такого запроса могут влиять виртуальные параметры, которые указываются в виде комментариев в SQL-запросе или в конфигурации роутера.

* Транзакции — при получении команды `BEGIN TRANSACTION` Sharded PostgreSQL не выполняет запросы немедленно. Вместо этого он сохраняет все последующие запросы в памяти (например, команды `SET`). Вся транзакция отправляется на конкретный шард целиком только при поступлении запроса, для которого можно однозначно определить целевой шард. Это позволяет выполнить всю транзакцию на одном шарде.

#### Как выполнять транзакции с несколькими шардами? {#multi-shard-transactions}

Для атомарных кросс-шардовых транзакций используйте двухэтапную фиксацию (2PC):

1. В начале сессии — `SET __spqr__commit_strategy TO '2pc'`.
1. В отдельной операции `COMMIT` — добавьте виртуальный параметр `/* __spqr__commit_strategy: 2pc */`.
1. Убедитесь, что на шардах установлена настройка `max_prepared_transactions > 0`.

  {% note warning %}

  Без 2PC изменения могут быть применены частично.

  {% endnote %}

Операции `COPY` поддерживаются с виртуальным параметром `/* __spqr__allow_multishard: true */`.

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

#### Как принудительно указать, на каком шарде выполнить запрос? {#how-to-specify-shard}

Чтобы указать шард для выполнения запроса, используйте виртуальные параметры:

* `/* __spqr__execute_on: <имя_шарда> */` — указывает конкретный шард для выполнения запроса.

  Чтобы узнать имя шарда, выполните SQL-запрос `SHOW shards;`.

* `/* __spqr__auto_distribution: ... */` — выбирает правило шардирования для маршрутизации.
* `/* __spqr__scatter_query: true */` — включает отправку запроса на все шарды.

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

Подробнее о настройках выполнения запроса в [документации SPQR](https://docs.pg-sharding.tech/routing/hints#__spqr__target_session_attrs).

#### Какие стратегии фиксации транзакций поддерживаются? {#commit-strategy}

Sharded PostgreSQL поддерживает однофазную и двухэтапную фиксацию.

Способ фиксации в распределенной транзакции задается виртуальным параметром `__spqr__commit_strategy`. Возможные значения:

* `1pc` — одноэтапная фиксация (best-effort фиксация).
* `2pc` — двухэтапная фиксация.

  Для двухэтапной фиксации используйте виртуальный параметр `/* __spqr__engine_v2: true */` и установите параметр PostgreSQL `max_prepared_transactions` на всех шардах.

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.

#### Как работают справочные таблицы (reference tables)? {#reference-tables}

Данные в таких таблицах реплицируются на все шарды. Запросы к ним автоматически рассылаются на все узлы с помощью двухэтапной фиксации.

#### Как создать справочные таблицы (reference tables)? {#how-to-create-reference-table}

Таблицы, идентичные на всех шардах, создаются через координатор:

```sql
CREATE REFERENCE TABLE table_name (...);
```

Данные автоматически реплицируются на все шарды. Запросы к ним выполняются без указания шардирования.

Подробнее о создании справочных таблиц в [документации SPQR](https://docs.pg-sharding.tech/sharding/console/sql_commands#create-reference-table).

#### Поддерживает ли Sharded PostgreSQL распределенные последовательности (distributed sequences)? {#distributed-sequences}

Да, через команду `CREATE REFERENCE TABLE ... AUTO INCREMENT`. Sharded PostgreSQL гарантирует уникальность автоинкремента на уровне кластера.

#### Можно ли шардировать связанные таблицы по одному ключу? {#single-key-sharding-for-connected-tables}
Да. Sharded PostgreSQL позволяет хранить связанные данные из разных таблиц на одном шарде, что упрощает JOIN-операции в пределах шарда.

#### Как выполняются запросы без явного ключа шардирования? {#queries-with-no-explicit-key}

По умолчанию запросы без ключа шардирования (мультишардовые запросы) запрещены. Их можно разрешить с помощью виртуального параметра `/* __spqr__scatter_query: true */`. Результаты с каждого шарда склеиваются, но без гарантии консистентности.

Виртуальные параметры можно задавать комментариями в SQL или через `SET`.