1 CREATE PROCEDURE bad_cursor( )
Delphi site: daily Delphi-news, documentation, articles, review, interview, computer humor.
В даний час MySQL пропонує односпрямовані (з прокруткою вперед) серверні курсори тільки для читання, і використовувати їх можна лише в процедурах, що зберігаються. Курсор дозволяє обійти результат запиту, витягуючи рядки в змінні для подальшої обробки. Зберігається процедура дозволяє відкривати відразу кілька курсорів, причому вони можуть бути вкладені один в одного (у вкладених циклах).
Можливо, в майбутніх версіях MySQL з'являться і курсори, що оновлюються, але в жодній з наявних зараз їх немає. Курсори допускають лише читання, тому що обходять тимчасові таблиці, а чи не таблиці, у яких зберігаються реальні дані.
Для непосвяченого пристрій курсорів у MySQL таїть чимало сюрпризів. Оскільки курсори реалізовані за допомогою тимчасових таблиць, у розробника може виникнути хибне відчуття ефективності. Найважливіше, що потрібно пам'ятати, це те, що курсор виконує весь запит у момент відкриття. Розглянемо таку процедуру:
1 CREATE PROCEDURE bad_cursor( )
3 DECLARE film_id INT;
4 DECLARE f CURSOR FOR SELECT film_id FROM sakila.film;
6 FETCH f INTO film_id;
У цьому прикладі видно, що курсор можна закрити до завершення обходу результатів. Розробник, який звик до Oracle або Microsoft SQL Server, можливо, і не помітить у цій процедурі нічого поганого, але в MySQL вона призводить до зайвої роботи. Профілювання за допомогою команди SHOW STATUS показує, що ця процедура виконує 1000 операцій читання індексу та 1000 операцій вставки. А все тому, що у таблиці sakila. film рівно 1000 рядків. Усі 1000 операцій читання та запису проводяться при обробці рядка 5, ще до початку виконання рядка 6.
Мораль полягає в тому, що раннє закриття курсору, що вибирає дані з великої таблиці, не дає жодної економії. Якщо потрібно лише кілька рядків, скористайтеся фразою LIMIT.
Через курсори MySQL може виконувати і додаткові операції введення/виводу, які іноді виявляються дуже повільними. Оскільки тимчасові таблиці в пам'яті не підтримують типи BLOB і TEXT, MySQL змушена створювати тимчасові таблиці на диску для курсорів, які витягують дані таких типів. Але якщо це не так, тимчасові таблиці, розмір яких перевищує значення параметра tmp_table_size, все одно створюються на диску.
MySQL не підтримує курсори на стороні клієнта, але в клієнтському API є функції, які емулюють курсор шляхом завантаження всього результуючого набору на згадку. Насправді це нічим не відрізняється від копіювання результату в створений додатком масив з подальшою маніпуляцією цим масивом. Щоб отримати додаткові відомості про наслідки завантаження всіх результатів у пам'ять клієнта, див. «Клієнт-серверний протокол MySQL» на стор.