Кому-то может показаться странным заголовок поста. И правда, зачем в здравом уме тормозить выполнение запросов на сервере?
Я вот отвечу: «Чтобы проверить как работает интерфейс программы-клиента во время длительных запросов». Такая задача возникла предо мной во время реализации импорта структуры базы для нашего ER-дизайнера.
Интерфейс программы, по моему скромному мнению, во время длительных запросов должен обеспечить три аспекта:
- Радовать глаз пользователя всякого рода статистикой и анимацией(?).
- Не дать пользователю нажать или сделать что-то не то.
- С другой стороны, обязательно дать возможность остановить длительный процесс.
Никто, конечно, не запрещает вставлять всякие sleep() в код програмы-клиента, но есть в этом что-то от лукавого. А можно использовать встроенную функцию pg_sleep(), параметром которой может быть передано количество секунд, на которое нужно остановить исполнение запроса.
SELECT pg_sleep(1.5);
Давайте затормозим запрос, возвращающий список таблиц в базе:
SELECT oid :: regclass
FROM pg_class
WHERE relkind = 'r'
Пример 1
Можно поместить вызов pg_sleep() в раздел FROM:
SELECT oid::regclass
FROM pg_class, pg_sleep(10)
WHERE relkind = 'r'
В таком случае функция выполнится всего один раз и общее время исполнения будет около 10 секунд. Более того, весь набор данных вернется сразу целиком.
Пример 2
Можно поместить вызов pg_sleep() в раздел SELECT:
SELECT oid::regclass, pg_sleep(1)
FROM pg_class
WHERE relkind = 'r'
В этом же случае функция выполнится по одному разу для каждой строки набора данных. А именно столько раз, сколько таблиц имеется в вашей базе. При таком подходе есть еще один плюс. Используя асинхронную обработку запроса, например так или эдак, можно получать строку одну за одной, и радовать пользователя, медленно ползущим прогресс-баром.
Всех вам благ!
Автор: pasha_golub