AndriyKo |
Anjey aka PM | Это одно из узких мест кода, через него будет проходить очень много запросов по 500-5000 в секунду у конечного клиента. |
Заинтриговал. А разве сервак с такой частотой справится ? В процедурке ж не только проверка на нуллы, селекты(апдейты, инсерты) тоже ж есть. Даже если только селекты из кеша и один клиент, всё одно не верится. Шо ж за задача такая самашечая, можешь рассказать ? Аж зудит, интересно :)) |
Нет, просто в одной процедуре таких проверок порядка 5-20 а селектов нету :)
есть вызов УДФ-ки в зависимости от результирующего параметра...
кстати сравним процедуры:
количество циклов 10 000 000
Просто сравнение без проверки на нул:
CREATE PROCEDURE NEW_PROCEDURE (
INPUT_VALUE INTEGER)
RETURNS (
OUTPUT_VALUE INTEGER)
AS
DECLARE VARIABLE A INTEGER;
DECLARE VARIABLE B INTEGER;
BEGIN
/* Procedure Text */
A = 5;
B = 1;
OUTPUT_VALUE = 0;
WHILE (OUTPUT_VALUE < INPUT_VALUE) DO
BEGIN
IF (A <> B) THEN
OUTPUT_VALUE = OUTPUT_VALUE + 1;
END
SUSPEND;
END
|
Время выполнения: 8,5 - 9,5с
использование COALESCE для проверки на нул:
CREATE PROCEDURE NEW_PROCEDURE (
INPUT_VALUE INTEGER)
RETURNS (
OUTPUT_VALUE INTEGER)
AS
DECLARE VARIABLE A INTEGER;
DECLARE VARIABLE B INTEGER;
BEGIN
/* Procedure Text */
A = 5;
B = 1;
OUTPUT_VALUE = 0;
WHILE (OUTPUT_VALUE < INPUT_VALUE) DO
BEGIN
IF (COALESCE(A,-1) <> COALESCE(B,-1)) THEN
OUTPUT_VALUE = OUTPUT_VALUE + 1;
END
SUSPEND;
END |
Время выполнения: 13-14 с.
Мой способ проверки при A <> NULL AND B <> NULL:
CREATE PROCEDURE NEW_PROCEDURE (
INPUT_VALUE INTEGER)
RETURNS (
OUTPUT_VALUE INTEGER)
AS
DECLARE VARIABLE A INTEGER;
DECLARE VARIABLE B INTEGER;
BEGIN
/* Procedure Text */
A = 5;
B = 1;
OUTPUT_VALUE = 0;
WHILE (OUTPUT_VALUE < INPUT_VALUE) DO
BEGIN
IF (A <> B OR (NOT (A IS NULL AND B IS NULL))) THEN
OUTPUT_VALUE = OUTPUT_VALUE + 1;
END
SUSPEND;
END |
Время выполнения: 8,5 - 9,5с (как в первом примере)
CREATE PROCEDURE NEW_PROCEDURE (
INPUT_VALUE INTEGER)
RETURNS (
OUTPUT_VALUE INTEGER)
AS
DECLARE VARIABLE A INTEGER;
DECLARE VARIABLE B INTEGER;
BEGIN
/* Procedure Text */
A = 5;
B = NULL;
OUTPUT_VALUE = 0;
WHILE (OUTPUT_VALUE < INPUT_VALUE) DO
BEGIN
IF (A <> B OR (NOT (A IS NULL AND B IS NULL))) THEN
OUTPUT_VALUE = OUTPUT_VALUE + 1;
END
SUSPEND;
END |
Время выполнения: 9,5 - 11с (даже быстрее чем с COALESCE хотя те-же 3 операции в идеале)
Для уверенности я проверил использование COALESCE для проверки на нул при одном из значений NULL:
Время выполнения 15-16 с (странно имхо)
Вывод: Прирост производительности 20-25% без COALESCE.
Оптимизация рулит :)
Согласен, разница небольшая да и задержки то не значительные, но если в в СП-хах сравниваются входные параметры а не результаты выборки и работы с даными нет вовсе (только вызов УДФ) то это ощутимо имхо.