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

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


person Aadith Ramia    schedule 03.02.2010    source источник
comment
Возврат конечных столбцов с использованием типа данных переменной длины может привести к дополнительным затратам на поиск.   -  person OMG Ponies    schedule 03.02.2010


Ответы (6)


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

person tvanfosson    schedule 03.02.2010

Я могу неправильно понять вопрос, но все же:

Абсолютное количество выбранных вами столбцов не имеет большого значения. Однако выбор столбцов, которые могут существенно различаться в зависимости от того, как индексируется таблица.

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

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

Быстрый пример для SQL Server 2005+ - допустим, это ваша таблица:

ID int NOT NULL IDENTITY PRIMARY KEY CLUSTERED,
Name varchar(50) NOT NULL,
Status tinyint NOT NULL

Если мы создадим этот индекс:

CREATE INDEX IX_MyTable
ON MyTable (Name)

Тогда этот запрос будет быстрым:

SELECT ID
FROM MyTable
WHERE Name = 'Aaron'

Но этот запрос будет медленным (er):

SELECT ID, Name, Status
FROM MyTable
WHERE Name = 'Aaron'

Если мы изменим индекс на покрывающий индекс, т.е.

CREATE INDEX IX_MyTable
ON MyTable (Name)
INCLUDE (Status)

Затем второй запрос снова становится быстрым, потому что механизму БД никогда не нужно читать строку.

person Aaronaught    schedule 03.02.2010
comment
+1 за показ кода и добавление указателя, показывающего, как работает INCLUDE - person SQLMenace; 03.02.2010

Ограничение количества столбцов не оказывает заметного влияния на запрос. Почти всегда в кэш извлекается целая строка. Проекция происходит последней в конвейере SQL.

Проекционная часть обработки должна выполняться последней (например, после GROUP BY), поскольку она может включать создание агрегатов. Кроме того, для обработки JOIN, WHERE и ORDER BY может потребоваться много столбцов. В результирующем наборе возвращено больше столбцов, чем окончательно. Вряд ли стоит добавлять в план запроса шаг для выполнения прогнозов, чтобы хоть как-то сэкономить немного операций ввода-вывода.

Проверьте документацию по плану запроса. В плане запроса нет узла "проект". Это небольшая часть формулирования набора результатов.

Чтобы уйти от «выборки всей строки», вам нужно перейти к столбцовой («перевернутой») базе данных.

person S.Lott    schedule 03.02.2010

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

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

person Jerry Coffin    schedule 03.02.2010

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

person SQLMenace    schedule 03.02.2010

Чтобы продемонстрировать то, что уже написал тванфоссон, что существует стоимость «передачи», я выполнил следующие два оператора на базе данных MSSQL 2000 из анализатора запросов.

ВЫБЕРИТЕ длину данных (текст) ИЗ syscomments

ВЫБРАТЬ текст ИЗ syscomments

Оба результата вернули 947 строк, но первый занял 5 мс, а второй 973 мс.

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

person Conrad Frix    schedule 03.02.2010