Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: Вопрос по limit и UNIQUE KEY
Покинул форум
Сообщений всего: 56
Дата рег-ции: Авг. 2017 Откуда: замкадье
Помог: 1 раз(а)
Во-первых, если нужно узнать только кол-во записей (предположительно 0 или 1) незачем использовать SELECT * ибо выбирает все поля, а они не нужны, лишняя работа, достаточно какое-нибудь одно поле. Другой вариант - использовать SELECT COUNT(*) только тогда проверку условия нужно будет изменить.
Во-вторых, никогда не передавайте что-либо, полученное от пользователя, напрямую, без обработки в SQL-запрос. В вашем случае вместо $_POST['login'] используйте addslashes($_POST['login'])
В третьих, да, видимо LIMIT 1 в таком случае не нужен.
Artix
Отправлено: 28 Декабря, 2017 - 12:24:27
Новичок
Покинул форум
Сообщений всего: 35
Дата рег-ции: Дек. 2017
Помог: 0 раз(а)
rgl пишет:
незачем использовать SELECT * ибо выбирает все поля, а они не нужны, лишняя работа,
"SELECT `login` FROM `users` WHERE `login` = '".$_POST['login']."'"
Я правильно понял???
Покинул форум
Сообщений всего: 56
Дата рег-ции: Авг. 2017 Откуда: замкадье
Помог: 1 раз(а)
"SELECT `login` FROM `users` WHERE `login` = '".addslashes($_POST['login'])."'"
Строитель
Отправлено: 28 Декабря, 2017 - 15:24:20
Участник
Покинул форум
Сообщений всего: 1580
Дата рег-ции: Февр. 2014 Откуда: Украина
Помог: 73 раз(а)
Artix пишет:
Если я использую в бд UNIQUE KEY `login` (`login`), LIMIT 1 можно в запросе не использовать?
Лично я далеко не эксперт в работе sql-баз данных, но если память мне не изменяет, с помощью оператора LIMIT можно существенно увеличить производительность sql-запроса, т.к. LIMIT прерывает его выполнение. Попробую объяснить на вашем примере:
Эта команда будет искать соответствия во всей таблице `users`, невзирая на уже найденное ранее соответствие условию WHERE `login` = 'login'. Иначе говоря, если в таблице 100 000 строк, то этим запросом будут затронуты все эти строки.
LIMIT 1 завершает поиск по БД после первого найденного соответствия. Вывод очевиден.
P.S.: Поправьте меня, если где-то ошибся.
Мелкий
Отправлено: 28 Декабря, 2017 - 15:50:09
Активный участник
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
Если есть уникальное ограничение и мы по нему ищем - то limit 1 бесполезен, т.к. планировщик и так знает, что по уникальному индексу не умеет смысла продолжать искать после первого совпадения.
rgl пишет:
лишняя работа, достаточно какое-нибудь одно поле
Есть большая разница между "какое-нибудь одно поле" и некоторое определённое поле.
Константу select 1 или выборка непосредственно полей по которым искали - допустимо использовать index only scan.
select primary_key_field - для mysql/innodb одно и то же, можно index only scan получить. Для других надо уточнять
выбор любого inline поля - надо идти читать его из таблицы
выбор external поля (большого text, например) - надо идти сначала в таблицу, затем ещё вычитывать отдельно лежащее содержимое этого файла
А для передачи данных для запроса - есть prepared statements. В mysql, впрочем, на редкость неудобные и лучше использовать pdo.
Подстановка данных в текст запроса должна настораживать сама по себе.
----- PostgreSQL DBA
Artix
Отправлено: 28 Декабря, 2017 - 15:50:13
Новичок
Покинул форум
Сообщений всего: 35
Дата рег-ции: Дек. 2017
Помог: 0 раз(а)
Строитель пишет:
Artix пишет:
Если я использую в бд UNIQUE KEY `login` (`login`), LIMIT 1 можно в запросе не использовать?
Лично я далеко не эксперт в работе sql-баз данных, но если память мне не изменяет, с помощью оператора LIMIT можно существенно увеличить производительность sql-запроса, т.к. LIMIT прерывает его выполнение. Попробую объяснить на вашем примере:
Эта команда будет искать соответствия во всей таблице `users`, невзирая на уже найденное ранее соответствие условию WHERE `login` = 'login'. Иначе говоря, если в таблице 100 000 строк, то этим запросом будут затронуты все эти строки.
LIMIT 1 завершает поиск по БД после первого найденного соответствия. Вывод очевиден.
P.S.: Поправьте меня, если где-то ошибся.
Это я знаю, тогда смысл с UNIQUE KEY ??
MouseZver
Отправлено: 29 Декабря, 2017 - 09:25:17
Новичок
Покинул форум
Сообщений всего: 58
Дата рег-ции: Июнь 2017 Откуда: php.ru
Помог: 1 раз(а)
Запрос в любом случае просмотрит все записи подошедшие по критерию и только потом будет применен LIMIT 1 (Добавление)
производительность LIMIT играет другую роль. (Добавление)
Мелкий пишет:
В mysql, впрочем, на редкость неудобные и лучше использовать pdo.
Покинул форум
Сообщений всего: 58
Дата рег-ции: Июнь 2017 Откуда: php.ru
Помог: 1 раз(а)
Мелкий пишет:
MouseZver пишет:
Запрос в любом случае просмотрит все записи подошедшие по критерию и только потом будет применен LIMIT 1
В общем случае утверждение неверно.
https://dev.mysql.com/doc/refman/5.7/en/limit-optimization.html
Не стоит путать производительность LIMIT с выведением результата и производительность LIMIT для поиска в таблице
Мелкий
Отправлено: 29 Декабря, 2017 - 10:11:35
Активный участник
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
MouseZver, а я и не путаю.
Имеющийся limit мало того, что не будет перебирать все совпадающие строки (за ненадобностью) - так ещё и может использовать вообще другой план запроса (основные моменты указаны в мануале, на который я сослался).
Мяч у вас. Докажите своё высказывание и объясните, почему limit 1 прервал seqscan преждевременно. В табличке лям строк, искомый i где-то в начале.
Для уникального индекса это всё, естественно, не играет роли, т.к. планировщик изначально знает гарантированную селективность уникального ограничения.
----- PostgreSQL DBA
Строитель
Отправлено: 29 Декабря, 2017 - 11:50:54
Участник
Покинул форум
Сообщений всего: 1580
Дата рег-ции: Февр. 2014 Откуда: Украина
Помог: 73 раз(а)
Мелкий пишет:
Имеющийся limit мало того, что не будет перебирать все совпадающие строки (за ненадобностью) - так ещё и может использовать вообще другой план запроса
Лично я уже запутался ... Ответьте мне, пожалуйста, моё утверждение о повышении производительности за счёт использования оператора LIMIT истинно? Или ложно?
Мелкий
Отправлено: 29 Декабря, 2017 - 13:12:40
Активный участник
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
Строитель пишет:
моё утверждение о повышении производительности за счёт использования оператора LIMIT истинно? Или ложно?
Два случая:
0) если есть unique по тому что ищем - то лимит роли не играет (гхм, ну кроме limit 0 - эта замечательная вещь даже выполняться не будет, ответит 0 строк сразу на этапе разбора)
Но и вреда от limit 1 не будет.
1) если уникального ограничения нет - лимит играет свою роль и прерывает выполнение запроса сразу по достижении нужного числа совпадений. И планировщик может менять план опираясь на знание того что надо достать только часть строк. Что совпадает с наблюдениями, если MouseZver не докажет обратное.
----- PostgreSQL DBA
Строитель
Отправлено: 29 Декабря, 2017 - 13:39:44
Участник
Покинул форум
Сообщений всего: 1580
Дата рег-ции: Февр. 2014 Откуда: Украина
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.