ВЫБРАТЬ только определенный набор строк одновременно - PullRequest
2 голосов
/ 12 марта 2010

Мне нужно выбрать данные из одной таблицы и вставить их в другую таблицу. В настоящее время SQL выглядит примерно так:

   INSERT INTO A (x, y, z)
   SELECT x, y, z
   FROM B b
   WHERE ...

Однако, SELECT огромен, в результате получается более 2 миллионов строк, и мы считаем, что он занимает слишком много памяти. Informix, в данном случае БД, исчерпывает виртуальную память при выполнении запроса.

Как мне выбрать и вставить набор строк (скажем, 2000)? Учитывая, что я не думаю, что есть какие-либо идентификаторы строк и т. Д.

Ответы [ 3 ]

3 голосов
/ 12 марта 2010

Вы можете выбрать SELECT FIRST n * из таблицы. Где n - это количество строк, которое вы хотите, скажем, 2000. Кроме того, в предложении WHERE сделайте встроенное выделение, которое проверяет таблицу, в которую вы вставляете, на наличие уже существующих строк. Так что при следующем запуске оператора он не будет включать уже вставленные данные.

0 голосов
/ 13 марта 2010

Я почти уверен, что IDS позволяет использовать только предложение FIRST, в котором данные возвращаются клиенту 1 , и это то, чего вы хотите избежать, если это вообще возможно.

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

Частично это зависит от того, насколько велик ваш набор данных и каковы ограничения - почему вы выполняете нагрузку между таблицами. Но я бы обычно стремился определить способ разделения данных на загружаемые подмножества и запускать их последовательно в цикле. Например, если порядковые номера находятся в диапазоне от 1 до 10 000 000, я мог бы выполнить цикл десять раз с условием использования порядкового номера для AND seqnum >= 0 AND seqnum < 1000000' and then И seqnum> = 1000000 И seqnum <2000000 'и т. Д. Предпочтительно на языке с возможность замены диапазона переменными. </p>

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


1 Чрезмерное упрощение. Например, хранимая процедура должна считаться «клиентом», а стоимость связи в хранимой процедуре (намного) меньше стоимости обращения к подлинному клиенту.

0 голосов
/ 12 марта 2010

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

total = SELECT COUNT(x) FROM B WHERE ...
while (total > 0) 
  INSERT INTO A (x, y, z) SELECT x, y, z FROM B b WHERE ... ORDER BY x LIMIT 2000
  total = total - 2000
end
...