2016-07-15 3 views
1

Я создаю API с использованием пакета Go (1.6.x) и вместе с PostGres (9.4). Должны ли мои подготовленные заявления иметь заявку или область запроса? Прочитав документы, представляется более эффективным охватить их на уровне приложений, чтобы сократить количество этапов подготовки. Однако, возможно, есть и другие соображения, и подготовленные заявления не рассчитаны на то, чтобы так долго жить?Перейти sql - подготовленная область сложения

ответ

1

Подготовленные операторы предназначены для выполнения повторяющихся команд SQL, которые могут отличаться, например, только значениями параметров.

Они не предназначены для того, чтобы жить «длинными», поскольку подготовленный оператор может (они делают, если вызывается из транзакции) резервировать активное соединение с базой данных («long» означает, когда они не используются, вполне нормально повторять выполнение подготовленное заявление много раз, даже если это займет много времени). Соединение является дорогостоящим ресурсом и должно выполняться только по мере необходимости. Просто создав кучу подготовленных операторов, а не закрывая их, вы можете выходить из активных/разрешенных соединений, а затем блокировать дальнейшую связь с сервером db.

Используйте подготовленный оператор, если вы хотите выполнить одно и то же заявление insert, update или select с разными параметрами несколько раз в одном (HTTP) запросе. Не используйте подготовленную инструкцию для извлечения (HTTP) запросов.

В некоторых реализациях драйверов и серверах баз данных подготовленные операторы могут также включать ресурсы, выделенные на самом сервере БД (не в приложении Go). Например, подготовленный оператор может быть предварительно скомпилирован на сервере БД, и сервер может подготовить план выполнения запроса, выделить для него определенные ресурсы, такие как память. Они могут сохраняться навсегда, пока не будет закрыто подготовленное заявление.

В статье приведена статья (размещенная Майлсом Макдоннеллом в комментариях ниже) в деталях реализации Prepared Statements в Go. В нем упоминается, что если подготовленные операторы не создаются из транзакций, они освобождают соединение обратно в пул соединений, но при необходимости они пытаются использовать то же самое, на котором они были подготовлены (потому что, если сервер db помогает/также играет активную роль в подготовленном заявлении он привязан к соединению со стороны сервера). Если нет, то они будут повторно подготовить их к новому соединению (что вызовет нежелательные эксплуатационные издержки).

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

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

+1

Я понимаю, что prep.stmt освобождает соединение, на котором оно было подготовлено обратно в бассейн. Затем stmt попытается использовать этот conn, когда он будет выполнен, но если соединение не будет доступно, он снова будет готов к новому подключению (сам по себе является проблемой масштабируемости). Учитывая затраты на создание и распределение ресурсов для операторов, так как мое приложение будет иметь конечное число операторов, мне кажется логичным создать их заблаговременно с областью применения. Я не согласен с вами обязательно, и я, вероятно, ошибаюсь, но у меня недостаточно четкое представление о том, почему. –

+0

Связь WRT между соединениями и подготовленными операторами; http://go-database-sql.org/prepared.html –