SQL переходит на вертикальные записи - PullRequest
1 голос
/ 28 октября 2010

У меня есть таблица (2 миллиона строк) в Informix v11.10, реплицированная (более 50 узлов) среда

Базовая компоновка выглядит так:
ID (PK) (int)
Division (int)
company (int)
feature1 char (20)
feature2 int
...
feature 200 char (2)

Есть несколько проблем, которые яИмеется с текущим макетом: с этой записью связано 200 «функций», но, возможно, 5-10 из них в любой момент времени не имеют значения по умолчанию / null (различаются для каждой записи).

Обновление всех записейдля компании иногда означало бы обновление 100 тыс. строк, что затрудняет репликацию и не поддается простому управлению.

Поэтому я внес в таблицу следующие изменения:
ID (int)
ID_TYPE (ID, подразделение или компания)
Имя_функции
Значение_функции

И имел другую таблицу только с:
ID (int)
Деление (int)
Компания (int)

Так, скажем, для ID # 1 в таблице будет 10 строк, а в связанном делении может быть несколько записей, илюбой может иметь несколько.Запись идентификатора «переопределит» любую запись с тем же именем feature_name, которое соответствует разделению, а разделение переопределит любую компанию.

Я создал функцию, которая при передаче идентификатора и имени feature_name запрашивает ее на основе компании.затем выполняет запрос на разделение, а затем на основе идентификатора и возвращает значение функции на основе вышеуказанной логики переопределения.(В основном это упорядоченный цикл foreach)

Затем я создал вид, похожий на:
выберите
my_func (feature1, ID) как feature1
my_func (feature2, ID) в качестве feature2
...
my_func (feature200, ID) как feature200
из таблицы

Теперь проблема в том, что я нажимаю на таблицу 200 * 3 (для ID, компании, подразделения) раз для каждогофункция, которая просто не собирается работать, это привязывает процессор.Новое число записей составляет около 20 миллионов и занимает гораздо меньше места.

Есть мысли?Мне кажется, что я где-то пропускаю временную таблицу, которая помешала бы ей попадать в таблицу с 20 миллионами строк 600 раз.

Ответы [ 2 ]

1 голос
/ 28 октября 2010

Вы не должны нажимать на свою таблицу 200 * 3 для каждой функции, но для каждой строки вашего представления - это потому, что ваше представление включает в себя 200 вызовов my_func для каждой строки (по одному на каждую функцию).

Возникает вопрос: вам когда-нибудь понадобится доступ ко всем 200 функциям одновременно? Из того, что было написано в вопросе, звучит так, как будто любой заданный идентификатор, вероятно, будет использовать только небольшое подмножество функций - любые запросы, которые относятся к конкретным функциям, вероятно, должны обращаться к my_func напрямую (а не через представление) для тех особенности.

С другой стороны, там, где необходимо извлечь все 200 функций, основание представления на 200 вызовах my_func гарантирует 600 логических обращений на каждую найденную строку. Вместо этого я предлагаю переписать представление для непосредственного доступа к таблице объектов с группировкой по идентификатору и с каждой функцией, полученной из структуры типа MAX(CASE WHEN .... Это все равно приведет к считыванию 600 физических строк, но не более 3-х логических операций чтения для каждой возвращенной строки представления - я ожидаю, что это будет работать значительно лучше.

0 голосов
/ 31 октября 2010

мой здравый смысл подсказывает, что вы должны нормализоваться в две отдельные таблицы.

...