Ответ
Это приведёт к полному сканированию таблицы (Full Table Scan), так как механизм партиционирования не сможет выполнить "отсечение партиций" (partition pruning). Запрос будет вынужден проверить каждую партицию, что сведёт на нет основное преимущество партиционирования — уменьшение объёма данных для чтения.
Конкретный пример в PostgreSQL:
-- Создаём таблицу, партиционированную по дате
CREATE TABLE sensor_data (
sensor_id INT,
recorded_at DATE,
value DECIMAL
) PARTITION BY RANGE (recorded_at);
CREATE TABLE sensor_data_2023 PARTITION OF sensor_data
FOR VALUES FROM ('2023-01-01') TO ('2024-01-01');
CREATE TABLE sensor_data_2024 PARTITION OF sensor_data
FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');
-- Запрос по партиционному ключу — БЫСТРО (чтение только из одной партиции)
SELECT * FROM sensor_data WHERE recorded_at = '2024-06-15'; -- Сканируется только sensor_data_2024
-- Запрос по НЕпартиционному ключу — МЕДЛЕННО (чтение из ВСЕХ партиций)
SELECT * FROM sensor_data WHERE sensor_id = 123; -- Сканируется sensor_data_2023 И sensor_data_2024
Как оптимизировать такой сценарий:
- Добавить индекс на столбец
sensor_id. Это ускорит поиск внутри каждой партиции, но не избавит от необходимости обхода всех партиций. - Изменить стратегию партиционирования, если это возможно по логике данных. Например, сделать составной ключ
PARTITION BY RANGE (recorded_at, sensor_id)или хэш-партиционирование поsensor_id. - Спроектировать запросы так, чтобы они всегда включали условие по партиционному ключу. Например, сначала найти диапазоны дат для нужного
sensor_id, а затем делать запрос с фильтром и поrecorded_at.
Вывод: Партиционирование — это не замена индексам, а инструмент для физического разделения данных. Его эффективность напрямую зависит от того, как вы фильтруете данные в запросах.
Ответ 18+ 🔞
А, ну это же классика, ёпта! Смотри, тут история про то, как партиционирование может накрыться медным тазом, если им неправильно пользоваться.
Вот представь: ты нагородил кучу партиций по дате, чтобы быстро искать данные за конкретный день. А потом приходит запрос, который ищет не по дате, а по какому-нибудь sensor_id. И что происходит? А происходит пиздец, Карл! Механизму партиционирования нужно выполнить так называемое "отсечение партиций" (partition pruning), чтобы не читать всё подряд. Но если в запросе нет условия по той колонке, по которой ты партиционировал, то отсечь нихуя не получится. Движку придётся лезть в каждую, блядь, партицию и там уже искать. Весь смысл партиционирования — уменьшить объём данных для чтения — летит коту под хвост. Получается полное сканирование таблицы (Full Table Scan), только ещё и по всем партициям разом. Удивление пиздец, да?
Вот смотри на примере PostgreSQL, тут всё понятно становится:
-- Делаем умную таблицу, разбитую по датам
CREATE TABLE sensor_data (
sensor_id INT,
recorded_at DATE,
value DECIMAL
) PARTITION BY RANGE (recorded_at);
-- Отдельная партиция за 2023 год
CREATE TABLE sensor_data_2023 PARTITION OF sensor_data
FOR VALUES FROM ('2023-01-01') TO ('2024-01-01');
-- И за 2024
CREATE TABLE sensor_data_2024 PARTITION OF sensor_data
FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');
-- Запрос по партиционному ключу — ЛЕТАЕТ! Читает только одну партицию.
SELECT * FROM sensor_data WHERE recorded_at = '2024-06-15'; -- Заглянет только в sensor_data_2024
-- А вот запрос по НЕпартиционному ключу — ПРОСРАЛСЯ. Полезет во все партиции подряд.
SELECT * FROM sensor_data WHERE sensor_id = 123; -- Будет рыться и в 2023, и в 2024, как свинья в огороде.
Ну и что с этим делать, спросишь ты? Варианты есть, но не все они панацея.
- Индекс на
sensor_idналепить. Это поможет быстрее искать внутри каждой отдельной партиции, но от обязательного обхода всех партиций тебя не спасёт. Так что это как подтереться бумажкой, когда у тебя понос — легче, но проблему не решает. - Пересмотреть всю стратегию партиционирования. Может, тебе на самом деле нужно партиционировать не по дате, а по
sensor_id, или сделать составной ключ? Но это уже архитектурные танцы с бубном, не всегда возможно. - Заставить разработчиков не выёбываться и писать запросы с условием по партиционному ключу. То есть, сначала как-то выяснить, в какие даты этот
sensor_id = 123вообще что-то записывал, а потом уже делать запрос с фильтром и поrecorded_at. Но это, блядь, лишняя работа для мозга.
Так что вывод простой, как три копейки: партиционирование — это не волшебная таблетка и уж точно не замена индексам. Это просто способ раскидать данные по разным физическим коробкам. А будет от этого толк или один вред — зависит целиком от того, как ты эти данные потом ищешь. Если ищешь не по тому ключу, по которому раскидал, то эффективность — ноль ебать.