Самый эффективный индекс для столбца BIGINT, который фильтруется / запрашивается только по положительному / отрицательному знаку? - PullRequest
0 голосов
/ 23 февраля 2019

Я унаследовал очень большую и активную таблицу PostgreSQL со столбцом BIGINT, содержащим скалярные измерения для сэмплов, например:

CREATE TABLE sample (
    id       SERIAL    PRIMARY KEY,
    name     TEXT      NOT NULL,

    ...
);

CREATE TABLE measurement (
    id       SERIAL    PRIMARY KEY,
    sampleid INTEGER   NOT NULL,
    value    BIGINT    NOT NULL,
    created  TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),

    ...

    FOREIGN KEY (sampleid) REFERENCES sample (id)
);

CREATE INDEX ix_measurement_created ON measurement (created);

Сначала пользователи запрашивают сэмплы, основываясь на том, что measurement.value больше нуля итогда по дополнительным критериям.Эти запросы изначально были мучительно медленными.

Добавление CREATE INDEX ix_measurement_value ON measurement (value); улучшило производительность почти в десять раз.

Я должен был быть доволен этим результатом, но я не могу не чувствовать, что это не самое эффективное решение.На практике фактические значения , хранящиеся в столбце, не имеют значения, так как 99% запросов:

  • ... всегда сначала для области value > 0 илиvalue <= 0.
  • ... никогда ищет значения в определенных диапазонах.
  • ... никогда ищет конкретные значения.

Будет ли одно из следующих действий более эффективным?

  • A single индексное выражение для:

    • CREATE INDEX ix_measurement_pos ON measurement (value > 0);
  • Отдельные индексные выражения для

    • CREATE INDEX ix_measurement_pos ON measurement (value > 0);
    • CREATE INDEX ix_measurement_neg ON measurement (value <= 0);

Я не уверен, как достаточно хорошо смоделировать статистику / загрузку производственной среды, чтобы самостоятельно оценить подходы (совет по этому поводу также был бы оценен!).

Редактировать: Я забыл упомянуть, что запросы генерируются / выдаются с помощью ORM, который я не могу контролировать - вышеприведенное объединение sample / measurement является лишь частью очень большой и ужасной вещи.

Редактирование # 2: Это база данных PostgreSQL 9.3, которую нельзя обновить до версии 9.4 в соответствии с требованиями поставщика.

Редактирование # 3: A частичный индекс было предложено, но поскольку запросы генерируются ORM, трудно определить, какие столбцы должен содержать частичный индекс ... если кто-то не посоветует это!

1 Ответ

0 голосов
/ 26 февраля 2019

Не видя конкретного запроса, производительность которого вас беспокоит, трудно ответить:

Было бы [эти конкретные индексы] более эффективными?[…] Я не уверен, как достаточно хорошо смоделировать статистику / нагрузку производственной среды, чтобы самостоятельно оценить подходы (совет по этому поводу также был бы оценен!).

Кажется, этобыть суть проблемы.

Чтобы оценить, что поможет конкретным запросам, вы хотите получить план выполнения по , используя EXPLAIN для этого конкретного запроса .

Если вы пытаетесь понять внутреннюю работу:

SELECT count(sampleid)
FROM measure
WHERE value > 0
;

, вы используете оператор EXPLAIN, указывающий, какое поведение должно быть в выходных данных.Например:

EXPLAIN (ANALYZE, BUFFERS, COSTS)
SELECT count(sampleid)
FROM measure
WHERE value > 0
;

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

Затем, чтобы проверить, улучшил ли ваш индекс то, что вы хотите, вам нужен какой-нибудь тестовый прогон, который будет забивать сервер запросами до и после предложенного вами изменения.Это даст вам тест производительности для сравнения до и после изменения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...