Запрос относительно выбора пункта - PullRequest
1 голос
/ 27 марта 2020

Мне нужно знать, какой из приведенных ниже запросов будет выполнен быстрее всего, учитывая:

a) оба имеют одинаковые строки, т.е. 500 миллионов, и не имеют первичного ключа и индексов.

b ) таблица имеет 30 столбцов (отдел, имя, адрес, -------- покупатель)

c) оба запроса выполняются независимо и впервые в базе данных Oracle.

Запрос 1:

select * from department;

Запрос 2 (выбор 4 столбцов из 30):

select dept,name,address,buyer from department;

Если запрос 2 будет выполнен первым, может кто-нибудь объяснить причину подробно? и если он завершается в одно и то же время, то почему?

Ответы [ 3 ]

3 голосов
/ 27 марта 2020

вы можете узнать, какой из двух запросов быстрее, просто запустив его. Однако первый может быть медленнее, потому что вы берете все поля таблицы, введя *. Второй способ, на мой взгляд, лучше, потому что в общем случае рекомендуется вставлять только те поля, которые вам нужны. Я всегда советую вам писать поля, которые вы хотите, чтобы запрос возвращал вам, потому что если однажды таблица изменит свою структуру, у вас не возникнет проблем. И наоборот, при вводе *, если однажды новые поля будут вставлены в таблицу, ваш запрос примет их, и если они не будут обработаны в бэкэнде, у вас могут возникнуть проблемы. Поэтому рекомендуется вводить только те поля, которые вам нужны.

2 голосов
/ 28 марта 2020

Запросы , вероятно, будут выполняться одинаково быстро, поскольку Oracle хранит данные таблицы в виде строк, а не отдельных столбцов. Выбираете ли вы один столбец или все столбцы, Oracle должен прочитать всю строку с диска или из памяти. (И поскольку Oracle хранит данные в 8-килобайтных блоках, он, вероятно, также будет читать более одной строки.)

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

  • Индексы - Если все столбцы являются частью индекса, Oracle может читать этот индекс, как тощую версию таблицы.
  • Материализованные представления - Как и в случае с индексами, в материализованном представлении может быть доступна уменьшенная версия таблицы.
  • LOB - Большие объекты обычно хранятся вне строки, в отдельном сегменте. Когда Oracle читает строку данных, если CLOB, BLOB, XML, et c., Не проецируются, Oracle не требуется доступ к этому отдельному сегменту.
  • Хранение в столбцах в памяти - Другой способ чтения только необходимых столбцов.
  • Связанные строки - Если строки слишком велики, чтобы поместиться в блоки (по умолчанию 8 килобайт) , тогда строка будет охватывать несколько блоков, и чтение только подмножества столбцов может избежать чтения другого блока. (Я не уверен на 100%, правда ли это на практике.)
  • Кэш результатов - Если используется кэш результатов, меньший набор результатов с большей вероятностью останется в кеше результатов .
  • Промежуточные наборы результатов - Если запрос более сложный и содержит объединения и другие операции, то Oracle будет создавать только промежуточные наборы результатов из необходимых столбцов. Oracle будет использовать меньшее временное табличное пространство для сортировки и хеширования, если будет использоваться меньше столбцов.
  • Сетевые издержки - Как отметил Алекс Пул, ваша общая производительность для такого простого запроса, вероятно, будет зависит больше от сети, чем от производительности базы данных.

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

0 голосов
/ 02 апреля 2020

Я бы сказал, что они оба будут выполнять одно и то же на стороне БД, но ваш клиент будет испытывать более низкую производительность в версии "select *", потому что он возвращает больше данных, и более 500 000 000 строк, которые вы, скорее всего, почувствуете сетевая задержка из-за большего объема данных. Это можно измерить на стороне клиента или на основе общего истекшего времени сеанса DBA_HIST_ACTIVE_SESS_HISTORY.

...