Задавайте вопросы, мы ответим
Вы не зашли.
еще вопросец
в теории (моей теории), при работе с процедуркой, а в особенности при необходимости сделать проверочный запрос на существование какого-либо значения по первичному ключу, стоит делать так:
if exists(SELECT 1 FROM `some_table` t WHERE t.`id` = _id LIMIT 1) then ... end if;
(_id - какойто входной аргумент, а `id` - поле таблицы, первичный ключ).
Но вот возник вопрос - насколько "умен" мускль: в случае нахождения нужного элемента по ПК или уникальному полю прекратит ли он дальнейший поиск?
т.е. будет ли с точки зрения скорости работы равны следующие запросы:
SELECT 1 FROM `some_table` t WHERE t.`id` = _id LIMIT 1;
SELECT 1 FROM `some_table` t WHERE t.`id` = _id;
Неактивен
В данном конкретном случае LIMIT не играет никакой роли. MySQL
понимает, что имеет дело с WHERE-указанием по уникальному ключу,
а значит - строчка получится всегда максимум одна. Такие запросы
проходят всегда с использованием индекса.
Если же индекс не уникальный - то LIMIT может значительно ускорить
обработку запроса. Без LIMIT оптимизатор будет оценивать cardinality
индекса, количество строк и другие параметры таблицы. Возможен случай,
когда индекс вообще не будет использоваться. В случае с LIMIT, он
остановится на одной строке, которую найдет опять же по индексу.
Неактивен
Т.е. получается что в таком случая я лишь усугубляю работу БД лишними критериями
спасибо!
да, кстате сразу хотел спросить, есть ли здравый смысл в использовании других конструкций кроме
if exists() then..
в телах функций, где добавление INSERT'ом дублирующих уникальных значение вызовет критическую ошибку 1062 (вроде ), которая очень нехорошо будет смотреться в PHP коде...
Отредактированно anky (24.04.2007 17:11:17)
Неактивен
Все зависит от Вашего стиля написания программы. IF EXISTS() требует
наличия транзакций, т.к. Вы не можете быть уверены, что строчка не появится
(или не исчезнет) вдруг вследствие работы другого потока.
Для MyISAM Вы можете пользоваться INSERT IGNORE или REPLACE, которые,
соответственно, не изменяют строчку (которая совпадает по уникальным
ключам) или заменяют ее на новые данные. При этом реально произведенное
действие можно оценить по количеству измененных строк: в случае обычного
добавления будет одна строка, в случае срабатывания IGNORE - будет изменено
ноль строк, в случае замены REPLACE - две (удаление + добавление новой).
Существует еще возможность обновлять строчку при совпадении уникальных
индексов: ON DUPLICATE KEY UPDATE. Обо всем этом, разумеется, можно
прочитать в документации.
Неактивен
дело в том что мне надо отслеживать результат - т.е. была ли успешно добавлена запись или нет.
конечно, как вариант - использовать в РНР mysql_affected_rows вместе с INSERT IGNORE...
стоит ли тогда менять?
вот кусок функции, в РНР уже идет обработка результата и вывод сообщений ,в случае ошибок (связанных с дублированием)
CREATE FUNCTION `p_de_users`(_login varchar(20)) RETURNS tinyint(1) begin if exists ( SELECT 1 FROM `v_id_users` t WHERE t.`login` = _login) then UPDATE `users` SET `users`.`deleted` = 1 where `users`.`login` = _login; return 0; end if; return -1; end
аналогично INSERT сейчас работает
Отредактированно anky (25.04.2007 18:58:40)
Неактивен
Для UPDATE никаких подковырок я тут не вижу, если запись есть,
то ее могут пометить удаленной два потока одновременно. В случае с
INSERT, у Вас могут быть проблемы с уникальными полями. Представьте
себе ситуацию, когда два потока пытаются это сделать одновременно.
Первый поток делает проверку на наличие строки: строки нету. Далее
процессор переключается на второй поток, который делает такую же
проверку и вставляет строчку. Процессор переключается на первый поток,
который пытается вставить строчку и получает ошибку. Спасти от этого
сможет только поддержка транзакций, которой в MyISAM нету. Поэтому,
если Вы используете таблицы MyISAM, я Вам рекомендую переписать
INSERT-версию процедуры через INSERT IGNORE. Для определения
успешности завершения операции внутри процедуры, можно использовать
ROW_COUNT().
С другой стороны, на не загруженном сервере вероятность одновременной
вставки, разумеется, очень мала.
Неактивен