2013-08-18 5 views
1

У меня есть основной таблицы пользователя в Postgresql,Postgresql SETOF против REFCURSOR

CREATE TABLE myuser (
userId bigserial primary key, 
user_name varchar(32), 
password varchar(32) 
); 

Я хочу, чтобы хранимая процедура для получения этой информации. Глядя на документацию здесь: posgresql call proc Я вижу, у меня есть в основном 2 разных варианта.

  1. Вернуть SETOF MyUser
  2. Вернуть REFCURSOR с данными, которые я хочу

Я использую Java, и я хочу знать, какая из них быстрее, и/или лучше. Каковы функциональные различия между ними? Похоже, что единственное различие заключается в том, как я настроил свой Java CallableStatement, но почему я должен выбирать один из них?

+1

ли это самый простой способ пока у вас не будет причины попытаться получить фантазию. 'SETOF' проще работать и, как правило, более безопасно. Используйте его, если вы не обнаружите, что у вас есть определенная причина, чтобы начать прыгать через обручи с refcursors. –

ответ

3

Я не гуру PostgreSQL, но из того, что я знаю о SQL, почти всегда лучше работать с наборами, чем с курсорами, поэтому я бы сказал - пойдите с SETOF.

В PostgreSQL также нет хранимых процедур, только функции.

+0

Это неверно во всех аспектах. Вы не должны использовать курсоры для эмуляции доступа ISAM (не для использования SQL). С SQL курсоры - очень практичный инструмент, в основном для больших данных или для лучшего удобства клиентов - вы можете получить первую строку N быстрее и показать ее с помощью курсоров. –

+0

@ PavelStehule спасибо за замечание, +1 для вас –

4

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

 
-- classic query 
SELECT * FROM generate_series(1,100000); 
-- 100000 rows is pushed to client at once 
-- less network handshaking, more client memory consumption 

-- cursors - more network handshaking, 
-- controlled memory consumption on client side 
BEGIN; 
DECLARE xx CURSOR FOR SELECT * FROM generate_series(1,1000000); 
FETCH 100 FROM xx; -- read 100 rows from server to client 
FETCH 100 FROM xx; -- read next 100 rows from server to client 
... 
COMMIT;