Есть ли смысл использовать MySQL «LIMIT 1» при запросе к индексируемому / уникальному полю? - PullRequest
34 голосов
/ 03 октября 2010

Например, я запрашиваю поле, которое, как я знаю, будет уникальным и индексируется, например, первичным ключом. Следовательно, я знаю, что этот запрос вернет только 1 строку (даже без LIMIT 1)

SELECT * FROM tablename WHERE tablename.id=123 LIMIT 1

или только обновление 1 строки

UPDATE tablename SET somefield='somevalue' WHERE tablename.id=123 LIMIT 1

Будет ли добавление LIMIT 1 улучшить время выполнения запроса, если поле будет проиндексировано?

Ответы [ 4 ]

40 голосов
/ 03 октября 2010

Есть ли смысл использовать MySQL «LIMIT 1» при запросах к первичному ключу / уникальному полю?

Не рекомендуется использовать LIMIT 1 при запросах с критериями фильтрации, которые соответствуют первичному ключу.или уникальное ограничение.Первичный ключ или уникальное ограничение означает, что в таблице есть только одна строка / запись с этим значением, и будет возвращена только одна строка / запись.Противоречиво иметь LIMIT 1 в первичном ключе / уникальном поле - кто-то, обслуживающий код позже, может ошибиться в важности и второй догадаться о вашем коде.

Но окончательный показатель - план объяснения:

explain SELECT t.name FROM USERS t WHERE t.userid = 4

... возвращает:

id  | select_type | table   | type  | possible_keys  | key      | key_len  |  ref  |  rows  |  Extra
-----------------------------------------------------------------------------------------------------
1   | SIMPLE      | users   | const | PRIMARY        | PRIMARY  | 4        | const | 1      |

... и:

explain SELECT t.name FROM USERS t WHERE t.userid = 4 LIMIT 1

... возвращает:

id  | select_type | table   | type  | possible_keys  | key      | key_len  |  ref  |  rows  |  Extra
-----------------------------------------------------------------------------------------------------
1   | SIMPLE      | users   | const | PRIMARY        | PRIMARY  | 4        | const | 1      |

Заключение

Без разницы, без необходимости.В этом случае он выглядит оптимизированным (поиск только по первичному ключу).

Как насчет индексированного поля?

Индексированное поле не гарантирует уникальность фильтруемого значения,может быть более одного случая.Так что LIMIT 1 имеет смысл, если вы хотите вернуть одну строку.

4 голосов
/ 03 октября 2010

Если поле имеет уникальный индекс, я вообще не вижу такого улучшения времени выполнения - оно растянуто даже по стандартам микрооптимизации.

Однако я вижу, что это потенциально маскирует другие проблемы. Скажем, вы добавляете LIMIT 1 к этим запросам, а затем каким-то образом поле, к которому вы обращаетесь, теряет свой уникальный индекс, и БД получает несколько строк с одинаковым значением. Этот код будет продолжаться долго и счастливо - я думаю, что вы могли бы вместо этого быстро потерпеть неудачу, чтобы осознать (и исправить) основную проблему.

В моем собственном коде интерфейса БД у меня есть метод queryOneRow (), который запускает некоторый SQL и выдает исключение, если он возвращает более одной строки назад. Для меня наиболее разумно обращаться с этим явным образом на прикладном уровне, а не с защитой в SQL.

1 голос
/ 03 октября 2010

В большинстве случаев, когда я запрашиваю уникальные поля, я все еще использую LIMIT 1.В основном я делаю это, потому что хочу убедиться, что независимо от того, что кто-либо делает с базой данных / таблицами, мой запрос никогда не вернет или не обработает более одной строки.

Как правило, это также должно охватывать случай динамически искаженного запросаиспортить всю базу данных (и нет - я не говорю о внедрении SQL).

0 голосов
/ 03 октября 2010

Поскольку запрос вернет в любой момент времени только одну запись;тогда добавление LIMIT 1 не увеличит ваше время выполнения.

Я не уверен, какой алгоритм использует MySQL для выполнения LIMIT 1 запросов.Как ни странно, он может использовать выражения сравнения или итераторы для возврата только 1 записи - в этом случае добавление LIMIT 1 может фактически задержать время выполнения несколькими инструкциями.

...