Какие аспекты SQL-запроса относительно дороги друг к другу?Присоединяется?Количество записей?столбцы выбраны? - PullRequest
0 голосов
/ 17 ноября 2010

Сколько будет стоить сравнение SELECT One, Two, Three с SELECT One, Two, Three, ..... N-столбец

Если у вас есть SQL-запрос, в котором две или три таблицы объединеныи извлекает ли 100 строк данных, может ли производительность сказать, нужно ли мне выбирать только то количество столбцов, которое мне нужно?Или я должен написать запрос, который просто объединяет все столбцы ..

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

Будет ли иметь значение 1 запись против 10 записей против 100 записей?

Ответы [ 10 ]

2 голосов
/ 17 ноября 2010

Несколько факторов влияют на стоимость запроса.

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

Далее, можно ли использовать предложение where, другими словами, может ли оно использовать индексы, даже если у вас есть правильные индексы? Плохое предложение where может повредить запросу гораздо больше, чем объединение или дополнительные столбцы. Вы не можете получить ничего, кроме сканирования таблицы, если используете синтаксис, который запрещает использование индекса, такого как:

LIKE '%test'

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

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

Мало того, что возвращение большего количества данных, чем вам нужно, заставляет SQL Server работать больше, оно заставляет запрос использовать больше сетевых ресурсов и больше памяти веб-сервера, если вы храните результаты в памяти. Это плохой выбор.

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

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

2 голосов
/ 17 ноября 2010

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

  1. Объединения - Особенно при объединении таблиц без индексов для полей, к которым вы присоединяетесь, и / или с таблицами, которые содержат очень большой объем данных.
  2. Количество строк / количество данных - Опять же, индексы немного смягчают это, просто убедитесь, что у вас есть правильные.
  3. Количество полей - я бы сказал, что количество полей в предложении SELECT влияет на производительность как минимум в большинстве ситуаций.

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

1 голос
/ 17 ноября 2010

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

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

Создайте запрос, который вам нужен, ЗАТЕМ беспокойтесь об его оптимизации, если производительность не соответствует вашим ожиданиям. Вы ставите лошадь перед телегой.

1 голос
/ 17 ноября 2010

Или я должен написать запрос, который просто возвращает все столбцы ..

Нет.Только сегодня был другой вопрос об этом .

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

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

0 голосов
/ 18 ноября 2010

Я предлагаю вам сначала рассмотреть ваши вопросы с точки зрения ввода / вывода. Дисковый ввод / вывод в моей системе SATA II составляет 6 Гбит / с. Пропускная способность моей памяти DDR3 составляет 12 ГБ / с. Я могу перемещать элементы в памяти в 16 раз быстрее, чем могу извлечь с диска. (Ссылка на Википедию и оборудование Тома)

Разница между получением нескольких столбцов и всех столбцов для ваших 100 строк может заключаться в зависимости от получения одной 8K-страницы с диска до получения двух или более страниц с диска. Когда страницы наконец находятся в памяти, перемещение двух столбцов или всех столбцов в хэш-таблицу выполняется быстрее, чем у любого инструмента измерения, который у меня есть.

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

0 голосов
/ 17 ноября 2010

Краткий ответ: не выбирайте больше полей, чем нужно - найдите «*» в исходном коде и хранимых процедурах;)

Вы всегда должны учитывать, какие части запроса будут вызывать какие расходы.

Если у вас хороший дизайн БД, объединение нескольких таблиц обычно обходится недорого. (Убедитесь, что у вас правильные показатели).

Основная проблема с «select *» заключается в том, что это приведет к непредсказуемому поведению в ваших результатах. Если вы напишите такой запрос И получите доступ к полям с помощью indexinx столбца, вы будете навсегда заблокированы в DB-Schema.

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

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

Наконец, следите за своим сервером SQL. Запустите профилировщик и попробуйте найти ваши худшие запросы. Запрос SQL не должен занимать больше полсекунды, в противном случае что-то, скорее всего, испорчено (Да ... есть операции, которые могут занимать гораздо больше времени, но у них должна быть причина)

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

0 голосов
/ 17 ноября 2010

Разница между SELECT One, Two, Three FROM ... и SELECT One,...,N FROM ... может быть как разница между днем ​​и ночью.Чтобы понять проблему, вам необходимо понять концепцию индекса покрытия :

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

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

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

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

В конечном счете, производительность запросов зависит только от одного фактора: количества операций ввода-вывода.И количество операций ввода-вывода в конечном итоге определяется путями доступа, доступными для удовлетворения запроса.Другими словами, путем индексации ваших данных.Невозможно писать эффективные запросы по плохим индексам.Можно писать плохие запросы по хорошим индексам, но чаще всего оптимизатор может компенсировать это и придумать хороший план.Вы должны потратить все свои усилия на лучшее понимание дизайна индексов:

0 голосов
/ 17 ноября 2010

Все, что говорят другие, - правда.

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

0 голосов
/ 17 ноября 2010

Соединения имеют потенциал , чтобы быть дорогим. В худшем случае, когда никакие индексы не могут быть использованы, им требуется время O (M * N), где M и N - количество записей в таблицах. Чтобы ускорить процесс, вы можете CREATE INDEX для столбцов, которые являются частью условия объединения.

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

0 голосов
/ 17 ноября 2010

Для ответа на вопрос:

Сколько стоило бы выбрать один, два, Три сравнивать с ВЫБРАТЬ Один, Два, Три, ..... N-колонка

Это не вопрос выбранной производительности, а количества времени, которое требуется для извлечения данных. Select * from Table и Select ID from Table преформы одинаковы, но выборка данных займет больше времени. Это идет рука об руку с количеством строк, возвращаемых запросом.

Что касается понимания исполнения, здесь есть хорошая ссылка

http://www.dotnetheaven.com/UploadFile/skrishnasamy/SQLPerformanceTunning03112005044423AM/SQLPerformanceTunning.aspx

Или Google Tsql Производительность

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...