Производительность и параметры связанного сервера - PullRequest
9 голосов
/ 25 сентября 2008

На работе у нас есть два сервера, один из которых запускает приложение, которое используют многие люди, и имеет серверную часть SQL Server 2000. Я был свободен запросить это в течение длительного времени, но не могу ничего добавить к нему, например, хранимые процедуры или дополнительные таблицы.

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

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

Также, какие опции связанного сервера у меня сейчас есть:

  • Collation Compatible True
  • Доступ к данным True
  • Rpc True
  • Rpc Out True
  • Использовать дистанционное сопоставление False
  • Имя сопоставления (пусто)
  • Время ожидания соединения 0
  • Тайм-аут запроса 0

EDIT:

Просто подумал, что обновлю этот пост. Я некоторое время использовал openqueries с динамическими параметрами для повышения производительности, спасибо за подсказку. Однако выполнение этого может сделать запросы более беспорядочными, поскольку вы в конечном итоге будете иметь дело со строками. наконец этим летом мы обновили SQL Server до 2008 и внедрили зеркалирование данных в реальном времени. Честно говоря, открытые запросы приближались к скорости локальных запросов для моих задач, но зеркалирование, безусловно, облегчило работу с sql.

Ответы [ 9 ]

8 голосов
/ 27 сентября 2008

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

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

Пример:

SELECT loc.field1, lnk.field1
FROM MyTable loc
INNER JOIN RemoteServer.Database.Schema.SomeTable lnk
  ON loc.id = lnk.id
  AND lnk.RecordDate = GETDATE()
WHERE loc.SalesDate = GETDATE()

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

Рекомендуемый метод - использование ОТКРЫТИЯ.

Избегая объединения с использованием OPENQUERY, локальный сервер отправляет запрос на выполнение только удаленно, а не отправляет набор идентификаторов для объединения.

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

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

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

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

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

И ПОЖАЛУЙСТА! Никогда не помещайте OPENQUERY (или любой связанный сервер) внутри цикла!

3 голосов
/ 27 сентября 2008

Королевская боль

У нас в магазине было несколько связанных серверов, и оказалось, что такой PITA .

Прежде всего, были серьезные проблемы с производительностью, аналогичные тем, что вы описываете. Я был шокирован, когда увидел статистику сетевого ввода-вывода. Несмотря на все усилия, нам не удалось намекнуть SQL Server на разумное поведение.

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

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

3 голосов
/ 25 сентября 2008

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

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

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

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

2 голосов
/ 25 сентября 2008

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

1 голос
/ 27 сентября 2008

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

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

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

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

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

Я не знаю ни одной хорошей статьи, на которую можно было бы указать. Когда я писал более сложные приложения для SQL Server, я начал думать, что мне нужно лучше понять, как работает SQL Server. С этой целью мы купили серию MS Press Inside Microsoft SQL Server 2005, отредактированную Каленом Делани, здесь, на работе. Том 1: Запоминающее устройство - определенно место для старта, но я не дошел до этого. Поскольку мои последние несколько проектов не были связаны с SQL Server, мои исследования стали слабыми.

0 голосов
/ 03 августа 2009

Динамический SQL и функция могут использоваться, чтобы обойти жестко заданный вопрос об имени. Например, я пытаюсь реализовать, где функция ufn_linkedDatabase (@purpose nvarchar (255)) с вводом 'cpi.cpi' (целевой CPI, подцелевая по умолчанию) возвращает «[SERVER-NAME.DOMAIN.LCL, 2000]. [CPI]» в производственной среде (где мы используем альтернативный номер порта для SQL Server, я не знаю почему, в том числе в имени связанного сервера). Затем команда SQL собирается в @template varchar (max) с выражением @ {cpi.cpi}, представляющим связанный сервер и базу данных, а затем @workstring = REPLACE (@template, N'@ndomcpi.cpi} ', ...). То, как функция на самом деле получает имя базы данных, отделено от процедур - таблица поиска хороша.

Проблемы - сделать OPENQUERY (), что, вероятно, еще лучше, по крайней мере, если параметр связанного сервера «совместимость сопоставления» не установлен в «истина», так что большая часть задачи может быть выполнена на связанном сервере - важно даже для Быстрая сеть, а внутренняя сеть нашей серверной комнаты довольно быстрая - чтобы сделать OPENQUERY (), мне, вероятно, нужно обрабатывать 'cpi.cpi.server' и 'cpi.cpi.database' и 'cpi.cpi.server.database' отдельно. И я могу закончить тем, что напишу ровно одно приложение, использующее этот дизайн, и в этом случае оно будет чрезмерно разработанным. Тем не менее, это означает, что сама функция не должна быть какой-то необычной работой.

В любом случае решение проблемы с быстрым сетевым оборудованием может быть более дешевым решением.

0 голосов
/ 20 июля 2009

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

Что решило мою проблему ...

Я обновил sql server 2000 с sp2 до SP4 и, если у вас уже есть sp4 на sql server 2000, запустите Instcat.sql. По своему опыту я могу заверить вас, что это сработает наверняка, если вы исчерпали все другие обходные пути.

Спасибо, Mithalesh mithalesh.gupta@gmail.com

0 голосов
/ 30 сентября 2008

Я бы посоветовал динамические открытые запросы в цикле курсора вместо связанных объединений. Это единственный способ реплицировать производительность связанного соединения MS Access (по крайней мере, для отдельных удаленных таблиц) Регулярные связанные объединения в ms sql слишком неэффективны, особенно если потянуть все в огромные таблицы.

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

0 голосов
/ 25 сентября 2008

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

...