Почему порог подготовленного оператора PostgreSQL JDBC по умолчанию равен 5? - PullRequest
4 голосов
/ 12 ноября 2011

По умолчанию пороговое значение оператора параметра установлено на 5 вместо 1. То есть

((PGStatement) my_statement).getPrepareThreshold()

всегда возвращает 5 по умолчанию.

В чем причина? Почему бы не использовать подготовленный оператор на стороне сервера в первые 4 раза выполнения запроса? Я не понимаю, почему я установил бы это значение, отличное от 1, и почему по умолчанию это значение не равно 1.

Можешь объяснить? Большое спасибо.

1 Ответ

5 голосов
/ 12 ноября 2011

Подготовленные операторы на стороне сервера используют ресурсы на стороне сервера для хранения плана выполнения оператора. Порог обеспечивает эвристику, которая заставляет операторы, которые фактически используются «часто», быть подготовленными. Определение «часто» по умолчанию равно 5.

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

Когда драйвер достигает порогового значения, он подготавливает оператор следующим образом:

    if (!oneShot)
    {
        // Generate a statement name to use.
        statementName = "S_" + (nextUniqueID++);

        // And prepare the new statement.
        // NB: Must clone the OID array, as it's a direct reference to
        // the SimpleParameterList's internal array that might be modified
        // under us.
        query.setStatementName(statementName);
        query.setStatementTypes((int[])typeOIDs.clone());
    }

Имя оператора отправляется как часть проводного протокола, который сообщает Postgres подготовить его на стороне сервера.

...