Должен ли я считать (*) или нет? - PullRequest
72 голосов
/ 19 января 2009

Я знаю, что вообще делать такие запросы - это плохая идея:

SELECT * FROM `group_relations`

Но когда я просто хочу подсчет, я должен пойти на этот запрос, так как это позволяет таблице измениться, но все равно дает те же результаты.

SELECT COUNT(*) FROM `group_relations`

Или более конкретный

SELECT COUNT(`group_id`) FROM `group_relations`

У меня есть ощущение, что последнее потенциально может быть быстрее, но есть ли еще что-то, что стоит рассмотреть?

Обновление : в этом случае я использую InnoDB, извините, что не уточнил.

Ответы [ 14 ]

1 голос
/ 27 марта 2009

Совет, который я получил от MySQL по поводу таких вещей, заключается в том, что попытка оптимизировать запрос на основе подобных трюков может быть проклятием в долгосрочной перспективе. В истории MySQL есть примеры, когда чья-то высокопроизводительная техника, основанная на работе оптимизатора, оказывается узким местом в следующем выпуске.

Напишите запрос, который отвечает на вопрос, который вы задаете - если вы хотите подсчитать все строки, используйте COUNT (*). Если вам нужно количество ненулевых столбцов, используйте COUNT (столбец), ГДЕ столбец не равен NULL. Индексируйте соответственно и оставьте оптимизацию оптимизатору. Попытки сделать свои собственные оптимизации на уровне запросов иногда могут сделать встроенный оптимизатор менее эффективным.

Тем не менее, есть несколько вещей, которые вы можете сделать в запросе, чтобы оптимизатор мог ускорить его выполнение, но я не верю, что COUNT является одним из них.

Редактировать: Статистика в ответе выше, тем не менее, интересна. Я не уверен, что в этом случае в оптимизаторе действительно что-то работает. Я просто говорю об оптимизации на уровне запросов в целом.

1 голос
/ 19 января 2009

если вы попробуете SELECT COUNT (1) FROM group_relations, это будет немного быстрее, потому что он не будет пытаться получить информацию из ваших столбцов.

COUNT (1) раньше был быстрее, чем COUNT (*), но это уже не так, поскольку современные СУБД достаточно умны, чтобы знать, что вы не хотите знать о столбцах

1 голос
/ 19 января 2009

Это должно зависеть от того, чего вы на самом деле пытаетесь достичь, как уже сказал Себастьян, то есть проясните свои намерения! Если вы просто подсчитываете строки, переходите к COUNT (*) или подсчитывая один столбец, переходите к COUNT (столбец).

Возможно, стоит проверить вашего поставщика БД. Когда я использовал Informix, у него была оптимизация для COUNT (*), стоимость выполнения плана запроса равнялась 1 по сравнению с подсчетом столбцов с одним или несколькими столбцами, что привело бы к более высокому значению

0 голосов
/ 23 июня 2009

Я знаю, что это вообще плохая идея такие запросы:

SELECT * FROM `group_relations`

Но когда я просто хочу считать, должен Я иду на этот запрос, так как это позволяет таблица, чтобы измениться, но все еще дает те же результаты.

SELECT COUNT(*) FROM `group_relations`

Как следует из вашего вопроса, причина SELECT * в том, что изменения в таблице могут потребовать внесения изменений в ваш код. Это не относится к COUNT(*). Довольно редко хочется иметь специализированное поведение, которое SELECT COUNT('group_id') дает вам - обычно вы хотите знать количество записей. Вот для чего COUNT(*), так что используйте его.

...