Гипотетическая производительность приводит к неиспользованию SELECT * - PullRequest
3 голосов
/ 06 октября 2010

В предисловии я знаю (как и вы!), Что использование SELECT * в производстве - это плохо, но я поддерживал сценарий, написанный кем-то другим.И я также знаю, что этот вопрос мал по конкретике ... Но гипотетический сценарий.

Допустим, у меня есть скрипт, который выбирает все из таблицы из 20 полей.Скажем, типичная информация о клиенте.

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

Какой тип выигрыша в производительности, если таковой имеется, можно ожидать, явно перечислив поля по сравнению с SELECT *?

Я скажу это, оба запроса используют один и тот жеточные показатели.Более конкретный запрос не имеет доступа к покрывающему индексу, который другой запрос не мог бы использовать, если вам интересно.

Я не ожидаю чудес, как добавление индекса, предназначенного для более конкретного запроса.Мне просто интересно.

Ответы [ 6 ]

7 голосов
/ 06 октября 2010

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

Если7 (или любое другое число) столбцов, которые вы оставляете, являются «дешевыми для извлечения» столбцами, а количество возвращаемых строк невелико, я бы ожидал очень небольшой выгоды.Если столбцы «дорогие» (например, они большие или являются BLOB-объектами, требующими ссылки на другой файл, который никогда не кэшируется) и / или вы получаете много строк, то можно ожидать значительного улучшения.Как много зависит от того, насколько дорого в вашей конкретной базе данных извлекать эту информацию и собирать ее в памяти.

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

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

При сравнении полей 13 против 20, если 7 пропущенных полей не являются полями типа CLOB / BLOB и т. Д., Я ожидаю, что заметного прироста производительности не будет.

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

Принцип плохости SELECT * имеет другую причину - стабильность системы.

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

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

Хм, в одном простом эксперименте я был удивлен, насколько это изменилось.

Я только что сделал простой запрос с тремя вариантами:

  1. выберите *
  2. выберите поле, которое является первичным ключом.(Может потребоваться получить это непосредственно из индекса без фактического чтения записи)
  3. выбрать неключевое поле.

Я использовал таблицу с довольно большим количеством полей -- 72 из них - включая один CLOB.Запрос был просто выбором с одним условием в предложении where.

Результаты:

Run  *     Key   Non-key
1   .647  .020  .028
2   .599  .041  .014
3   .321  .019  .027
avg .522  .027  .023

Ключ против неключа, похоже, не имел значения.(Что меня удивляет.) Но получение только одного поля вместо select * спасло 95% времени выполнения!

Конечно, это один крошечный эксперимент с одной таблицей.Там может быть много много соответствующих факторов.Я, конечно, не утверждаю, что вы всегда будете сокращать время выполнения на 95%, не используя select *!Но это гораздо более впечатляюще, чем я ожидал.

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

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

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

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

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

Выбрать * означает, что базе данных требуется время для поиска полей. Если вам не нужны все эти поля (а в любое время у вас есть внутреннее соединение, то вам это не нужно, поскольку поле соединения повторяется!), Тогда вы тратите впустую ресурсы сервера, чтобы получить данные, и ресурсы сети для их передачи. Вы также можете тратить память на удержание набора записей для работы с ним. И хотя повышение производительности может быть незначительным для одного запроса, сколько раз этот запрос выполняется? И люди, которые используют эту ужасно плохую технику, как правило, используют ее повсюду, поэтому исправление их всех может стать серьезным улучшением не таких больших усилий. А насколько сложно указать поля? Я не знаю о каждой базе данных, но в SQL Server я могу перетащить то, что я хочу, из браузера объектов за считанные секунды. Таким образом, использование select * тратит меньше минуты времени на разработку с худшей производительностью каждый раз, когда выполняется запрос, и создает код, который хрупок и подвержен очень серьезным проблемам при изменении схемы. Я не вижу причин использовать select * в рабочем коде.

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

Почему бы вам сами не попробовать и не сообщить нам?

Все будет зависеть от количества столбцов и их ширины.

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

...