Автоматическая переформулировка условия в представлении PostgreSQL - PullRequest
4 голосов
/ 04 октября 2011

У меня есть таблица следующего вида:

[mytable]
id,    min,     max,    funobj
-----------------------------------------
1      15       23      {some big object}
1      23       41      {another big object}
1      19       27      {next big object}

Теперь предположим, что у меня есть вид, созданный так:

CREATE VIEW functionvalues AS
SELECT id, evaluate(funobj)
FROM mytable

где оценка - функция, возвращающая множество, оценивающая большой funobj. Результат просмотра может выглядеть примерно так:

id,  evaluate
--------------
1    15
1    16
1    ...
1    23
2    23
2    24
2    ...
2    41
...

У меня нет никакой информации о конкретных значениях, которые получит оценка, но я знаю, что они всегда будут между минимальными и максимальными значениями, указанными в mytable (включая границы)

Наконец, я (или, что лучше, стороннее приложение) делает запрос на представление:

SELECT * FROM functionvalues 
WHERE evaluate BETWEEN somevalue AND anothervalue

В этом случае Postgres выполняет оценку функции для каждой строки в mytable, тогда как, в зависимости от предложения where, функцию не нужно оценивать, если ее max и min не находятся между заданными значениями. Поскольку оценка является довольно медленной функцией, это дает мне очень плохую производительность.

Лучшим способом было бы запросить таблицу напрямую, используя

SELECT *
FROM (
    SELECT id, evaluate(funobj)
    FROM mytable
    WHERE
       max BETWEEN somevalue AND anothervalue
       OR min BETWEEN somevalue AND anothervalue
       OR (min < somevalue AND max > anothervalue)
) AS innerquery
WHERE evaluate BETWEEN somevalue AND anothervalue

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

P.S .: Не стесняйтесь предлагать лучшее название для этого вопроса, тот, который я дал, довольно ... ну ... не конкретен.

Ответы [ 3 ]

1 голос
/ 04 октября 2011

У меня нет полного ответа, но некоторые из ваших лозунгов прозвенели в моей голове далекий звонок:

  • у вас есть представление
  • Вы хотите более интеллектуальный взгляд
  • вы хотите «переписать» определение представления

Это требует Система правил PostgreSQL , особенно часть "Представления и система правил". Возможно, вы можете использовать это в своих интересах.

Будьте осторожны: это коварная штука. Сначала вы найдете это замечательно, затем вы будете ласкать его, затем оно оторвет вашу руку без предупреждения, все еще мурлыкая. Перейдите по ссылкам в здесь .

0 голосов
/ 04 октября 2011

Иногда правильный ответ - «более быстрое оборудование».Учитывая то, как работает оптимизатор PostgreSQL, лучше всего было бы переместить таблицу и ее индексы на твердотельный диск.

Документация для табличных пространств

Во-вторых, табличные пространства позволяют администратору использовать знания о шаблонах использования объектов базы данных для оптимизации производительности.Например, индекс, который очень интенсивно используется, может быть размещен на очень быстром, высокодоступном диске, таком как дорогостоящее твердотельное устройство.В то же время таблица, хранящая архивные данные, которые редко используются или не критичны по производительности, могут храниться в менее дорогой, более медленной дисковой системе.

В октябре 2011 года вы можете получить действительно хорошие 128Гигабитный SSD-накопитель менее чем за 300 долларов или 300 гигов за менее чем 600 долларов.

Если вы ищете улучшение на два порядка, и вы уже знаете, что узким местом является ваша функция оценки (), товам, вероятно, придется принять меньшие выгоды из многих источников.Если бы я был вами, я бы посмотрел, может ли что-то из этого помочь.

  • твердотельный диск (коэффициент ускорения 50 по сравнению с жестким диском, но вы говорите, что не связаны с IO, поэтомудавайте оценим «2»)
  • более быстрый ЦП (ускорение 1,2)
  • больше ОЗУ (ускорение 1,02)
  • различные алгоритмы оценки () (скажем, 2)
  • разные структуры данных в методе define () (в функции базы данных, вероятно, 0)
  • разные оптимизации компилятора C (0)
  • разные компиляторы C (1.1)
  • переписать критически важные части оценки () в ассемблере (2.5)
  • для разных платформ DBMS
  • для разных технологий баз данных

Эти оценки предполагают ускорение в несколько разтолько 13. (Но они немного больше, чем догадки.)

Я мог бы даже рассмотреть нацеливание на GPU для расчета.

0 голосов
/ 04 октября 2011

Postgres не может выдвинуть ограничения из дерева запросов в функцию;функция всегда должна сканировать и возвращать всю базовую таблицу.И присоединиться к нему с тем же столом.вздох.«Разбиение» тела функции и объединение его с остальной частью запроса потребовало бы макроподобной функции вместо функции.

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

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

...