Проблемы с производительностью при использовании SELECT *? - программирование

Проблемы с производительностью при использовании SELECT *?

Возможный дубликат:
Что быстрее/лучше? SELECT * или SELECT column1, colum2, column3 и т.д.
В чем причина не использовать select *?

Есть ли проблема с производительностью при использовании SELECT *, а не в SELECT FiledName, FiledName2...?

4b9b3361

Ответ 1

Если вам нужно подмножество столбцов, вы оказываете плохую помощь оптимизатору (не можете выбрать индекс или не можете перейти только к индексу,...)

В некоторой базе данных можно выбирать только данные из индексов. Эта вещь очень полезна и дает невероятное ускорение. Выполнение запросов SELECT * не позволяет использовать этот трюк.

Во всяком случае, с точки зрения применения не является хорошей практикой.


Пример:

  • У вас есть таблица T с 20 столбцами (C1, C2,..., C19 C20).
  • У вас есть индекс на T для (C1, C2)
  • Вы делаете SELECT C1, C2 FROM T WHERE C1=123
  • Оптимизатор имеет всю информацию об индексе, не нужно идти в таблицу данных

Вместо этого, если вы SELECT * FROM T WHERE C1=123, оптимизатор должен получить все данные столбцов, то индекс на (C1, C2) не может быть использован.

В объединениях для нескольких таблиц очень полезно.

Ответ 2

Взгляните на это сообщение:

В чем причина не использовать select *?

и они:

Ответ 3

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

Кроме того, при вставке записей никогда не используйте select * в вставке в случае добавления столбцов.

Ответ 4

Единственная проблема с производительностью будет заключаться в том, что вашему приложению требуется только подмножество полей, возвращаемых select *. В базе данных нет разницы в производительности, так как они фактически одинаковы.

Ответ 5

Я не знаю о производительности вычислений, но с точки зрения способности чтения/поддержания (т.е. производительности человека) мы не используем select * в моем магазине. Все явно выбрано.

Ответ 6

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

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

ПРИМЕЧАНИЕ. Производительность кеширования работает только в том случае, если запрос будет запускаться несколько раз, особенно в течение небольшого периода времени, так что в противном случае вы не увидите разницы в производительности.

Ответ 7

Может быть. Это во многом зависит от механизма базы данных, того, как он хранит материал, сколько строк возвращается, сколько других столбцов есть и размеры других столбцов.

Если вы используете базу данных на основе строк (т.е. большую часть из них), которая хранит все столбцы вместе (почти все делают, за исключением BLOB, которые часто хранятся отдельно, особенно более крупные), тогда при выполнении SELECT * влияние на сам сервер - в любом случае он должен получить всю строку.

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

Если у вас большие капли в строках, SELECT * не очень умный, в противном случае вряд ли это будет иметь большое значение, но может.

Есть несколько "баз данных", основанных на базе столбцов, - они совершенно разные - для них "SELECT *" - это общий убийца производительности; обязательно избегайте этого. Скорее всего, если вы используете его, вы все это осознаете (обычно они используются для очень больших приложений для хранилищ данных).

Для меня главным преимуществом использования "SELECT *" является ремонтопригодность. Вы не получаете никаких сюрпризов, когда кто-то добавляет дополнительные столбцы в таблицу; ваш запрос "не быстро", когда кто-то удаляет один из столбцов, которые вы использовали. Это делает код более самодокументированным, так как кто-то может случайно увидеть, какие столбцы вам нужны.

Ответ 8

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

Есть проблемы с читабельностью и ремонтопригодностью с SELECT *. Имеет смысл использовать определенные имена полей все время, даже если вы хотите выбрать все поля.

Ответ 9

Производительность, немного. Это немного неуклюжие: в таблице, скажем, с 10 столбцами, объединенными на двух других таблицах или даже больше, особенно с большими наборами результатов, SELECT * может возвращать десятки столбцов, часто с преимущественно неиспользуемыми или даже бесполезными данными. Что касается хита в СУБД, их было бы не так много, но все эти данные по-прежнему должны каким-то образом путешествовать по проводу; пропускная способность сети и последующие задержки, безусловно, складываются. Я видел это из первых рук в больших объемах. Это определенно важно.

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

Ответ 10

Если вы используете select * в соединении, вы автоматически отправляете больше информации, чем вам нужно, потому что поля объединения повторяются. Это пустая трата времени обработки и сетевых ресурсов и может вызвать проблемы с производительностью. Дальнейшее указание полей не означает, что ваше приложение может сломаться при добавлении новых полей, особенно если это поля, которые пользователь не должен видеть, но которые существуют для проверки или обработки типа базы данных. Выбор * в вставке - это всегда плохая идея, так как где-то вдоль линии какой-то somen, который менее умный, может фактически изменить порядок столбцов в таблице.

Ответ 11

Предположительно да. Я искренне говорю на работе, что никогда не должен использовать SELECT *. Фактически, это в нашей политике не использовать его, потому что: а) это означает наличие двусмысленности в том, что используется и что доступно, просто просматривая запрос и б) он медленнее, так как SQL-сервер должен найти каждый столбец, в котором он нуждается, и вернуть их.

Я никогда не видел никаких доказательств этого.

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

Ответ 12

SELECT * переводится в SELECT Field1, Field2.... и т.д., прежде чем он будет запущен, чтобы они были фактически одинаковыми. Никакой разницы в производительности.

Однако удобство чтения и работоспособности лучше, когда его SELECT Field1, Field2..

Ответ 13

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

Я лично использую его все время.

Ответ 14

Если вы используете только подмножество полей, разница в производительности может быть существенной. См. Следующий пример, который включает в себя извлечение 1,411,771 строк из CScout анализ кода Linux.

$ time sh -c "echo 'select * from IDS' | mysql cslinux >/dev/null"
real    0m5.622s
user    0m2.580s
sys     0m0.532s

$ time sh -c "echo 'select EID from IDS' | mysql cslinux >/dev/null"
real    0m4.492s
user    0m0.716s
sys     0m0.096s

Это даже не влияет на влияние производительности на сервере.

Ответ 15

Если вы встраиваете sql в код, тогда вы всегда должны использовать длинную форму для ясности, а не для производительности. Для специальных запросов синтаксис select * ESSENTIALLY не менее эффективен, чем указание имен столбцов, если у вас нет большого количества столбцов, которые вы не должны, если вы не денормализуете.

Я должен получить 1 балл за использование 2 исключений в предложении и по-прежнему использовать их смысл!:)

Ответ 16

SELECT * требует, чтобы SQL находил все имена столбцов, но это не самый большой удар производительности при длинном снимке.

Самый большой удар производительности оператора SELECT * - это когда вы выполняете запрос, для которого требуется оценить некластеризованный индекс. Даже если некластеризованный индекс является индексом покрытия каждого столбца, SQL по-прежнему будет искать первичный ключ и получать значения из кластерного индекса.

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

Ответ 17

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

Например: выберите count (1) из... и выберите count (*) из...

В этом примере RDBMS нужно только знать, что ему нужен счетчик первого столбца, а ZING - выключен. В (к сожалению) более общем выборе count (*) RDBMS извлекает список всех столбцов, а затем проверяет каждую строку, чтобы определить, действительна ли она для подсчета (в отличие от проверки только 1-го столбца).

Это отлично работает большую часть времени. Я почти уверен, что большинство систем БД подсчитывают значения NULL в счете, но вы должны следить за этим и проверять, прежде чем принимать.

YMMV, void, где запрещено, и т.д.!

Ответ 18

Производительность Это всегда будет плохо, если вам не нужны все столбцы. Возвращая больше данных, чем требуется, будет дросселировать базу данных и вашу полосу пропускания lan/wan.

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

* Тестирование Если вы измените схему, весь ваш код, который использует SELECT * внутри , должен быть недействительным, потому что любые тесты, которые вы пишете для проверки метаданных, должны проверять вывод представления, proc.

* Конечно, если у вас есть тесты на месте, так как все хорошие DB Dev должны иметь:)

Ответ 19

Я согласен с почти всеми ответами, кроме определенных требований к производительности. Если вы на самом деле собираетесь использовать все столбцы в таблице, я бы сказал, что версия SELECT * является быстрее smidgen. Вот почему:

Возьмите эти два запроса в таблице, где есть уникальный индекс (id, x):

SELECT x,y,z,w FROM tab WHERE id='abc' ORDER BY s

SELECT x,y,z,w FROM tab WHERE id='abc' 
AND x in ('a','b','c','d','e','f','g','h',...)
ORDER BY ('a','b','c','d','e','f','g','h',...)

Что быстрее? Если предложение "x in" называет все значения для x в таблице для id 'abc', то первый запрос, вероятно, быстрее. Теперь переименуем эти поля:

SELECT field_name, field_type, field_offset, field_len
FROM internal_field_catalog
WHERE table_name = 'abc'
ORDER BY field_order

Таким образом, при извлечении данных SELECT * позволяет движку выполнять (эквивалент) одну memcpy для перемещения данных строки в результирующий набор, а при извлечении данных поля он, вероятно, выбирается быстрее.

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