|
Программирование >> Полное сканирование таблицы
для этой проблемы сушествует решение - в SQL нужно использовать шаблон, приведенный ниже. В решении используется синтаксис вложенных таблиц DB2. В разделе FROM внешнего запроса содержится другой запрос, который с точки зрения внешнего запроса обрабатывается как одна таблица: SELECT ... FROM (SELECT ... FROM (SELECT ... FROM <Bce внутренние соединения и десять внешних соединений> WHERE <условия. относящиеся к максимально вложенной таблице >) Т1 LEFT OUTER JOIN <внешние соединения с 11-го по 20-е> WHERE <условия. если таковые существуют, относящиеся к этой вложенной таблице, находящейся на самом внешнем уровне>) Т2 LEFT OUTER JOIN <остальные внешние соединения (максимум ЮР WHERE <условия. если таковые существуют, относящиеся к внешнему запросу> Этот шаблон подходит для запроса с 21-30 таблицами с внешними соединениями. Если внешними соединениями соединяются 11-20 таблиц, вам понадобится только одна вложенная таблица. Если таблиц больше 30, то потребуется больший уровень вложенности. Для такого синтаксиса DB2 эффективно создает вложенные представления на лету , как определено запросами внутри круглых скобок в разделах FROM. Для успешной обработки внешних соединений DB2 обрабатывает все небольшие запросы независимо, уходя от проблемы слишком большого количества внешних соединений в одном запросе. ПРИМЕЧАНИЕ На преяьщущем месте работы, в TenFold, мы обнаружили, насколько полезна эта техника, расширили продукт EnterpriseTenFold, чтобы при необходимости он автоматически генерировал этот исключительно сложный SQL-код. Вероятно, это не самое простое решение для кода, написанного вручную, но все равно этот метод вполне может быть единственным эффективно работающим решением для случая с медленным или слишком сложным разбором множества внешних соединений в DB2. Как принудить DB2 оптимизировать стоимость считывания первых строк обычно DB2 подсчитывает стоимость вьшолнения всего запроса и выбирает план, который должен выполняться быстрее от начала до конца. Однако, особенно для оперативных запросов, важнее всего получить только первые несколько строк, и вы предпочитаете оптимизацию в целях скорейшего получения первых строк. Чтобы быстро считать первые строки, обычно при помощи вложенных циклов, нужно добавить фразу OPTIMIZE FOR <п> ROWS (или OPTIMIZE FOR 1 ROW), где <n> -это количество строк, которые вы хотите получить быстрее, из большого набора строк, который теоретически вернет запрос. Этот оператор находится в самом конце запроса и сообщает DB2, что необходимо оптимизировать стоимость возвращения только первых <п> строк, не обращая внимания на стоимость вьшолнения оставшейся части запроса. Если вы точно знаете, сколько строк хотите получить, и доверяете оптимизатору выбор наилучшего плана, то можете выбрать <л>, исходя из этих начальных условий. Если вы хотите заставить надежный план со вложенными циклами начать выполняться как можно скорее, используйте OPTIMIZE FOR 1 ROW. На практике этот метод обычно приводит к использованию соединений со вложенными циклами, так как в этом случае для начала соединения не требуется считывать наборы строк полностью. Однако явно указанное выражение ORDER BY может свести на нет любую попытку быстро получить первые строки. Она обычно требует сортировки, которая выполняется после завершения запроса, откладывая возвращение первой строки независимо от плана вьшолнения. Если вы хотите использовать соединения с вложенными циклами, применяя эту технику, то можно удалить условие сортировки и произвести сортировку в приложении. Подсказка OPTIMIZE FOR 1 ROW эквивалентна подсказке FIRST ROWS в Oracle и подсказке OPTIONCFAST 1) в SQL Server. В DB2 мало методов, которые помогают использовать точно выбранные планы вьшолнения, в противоположность огромному количеству подробностей, которые DB2 предлагает для уже существующего плана выполнения, объясняя, почему был выбран именно он. Но я должен признаться, что доступные техники в сочетании с хорошим оптимизатором DB2 на моей практике проявляли себя замечательным образом. Управление планами в SQL Server Процесс настройки в SQL Server состоит из трех основных шагов. 1. Предоставление оптимизатору хорошей статистики по таблицам и индексам, чтобы он мог точно подсчитать стоимость различных вариантов. 2. Изменение запроса, чтобы запретить нежелательные планы выполнения, используя, в основном, методы, характерные для SQL Server. 3. Если необходимо, принудительный выбор простого плана выполнения при помощи инструкции FORCEPLAN. Подготовка к оптимизации в SQL Server в очередной раз доказывая, что недостаток знания опасен, стоимостные оптими- заторы часто выдают плохие результаты, если им не предоставлена статистика по всем таблицам и индексам, участвующим в запросе. Таким образом, вам обязательно нужно поддерживать достоверную статистику по таблицам и индексам, и помимо этого, заново генерировать статистику в случае, если объем таблицы существенно изменяется или перестраиваются таблицы или индексы. Самый безопасный способ - периодически заново генерировать статистику, используя для этого отрезки времени, когда нагрузка невелика, например, это может быть ночь или выходные. В Query Analyzer выполните следующую команду, затем скопируйте и вставьте полученные команды UPDATE STATISTICS в окно запроса и снова выполните их: -- file called updateal1.sql -- update your whole database SELECT UPDATE STATISTICS . name FROM sysobjects WHERE type = U Часто в запросах встречаются условия для сильно асимметричных распределений, например условия по специальным типам, кодам или флагам в случае, когда в этих столбцах присутствует лишь несколько различных значений. SQL Server автоматически создает статистику по распределению значений индексированных столбцов, позволяя автоматически устанавливать значения селективности, даже если индексированные столбцы характеризуются асимметричным распределением значений. Иногда бывает полезно помочь SQL Server определить селективность условия с асимметричным распределением, даже если это распределение относится к не индексированному столбцу. В таком случае вам необходимо особым образом запросить данные из этого столбца. Например, чтобы получить статистическую группу с именем Ef 1 ад по не индексированному столбцу Exempt Fl ад таблицы Empl oyees, выполните: CREATE STATISTICS EFlag on Empl oyees (ExemptJIag) В качестве примера случая асимметричного распределения возьмем таблицу Orders, в поле StatusCode которой может быть три значения: CL для закрытых (например, выполненных) заказов, СА для отмененных заказов и ОР для открытых заказов. Таким образом, большинство заказов будет выполнено, то есть если приложение проработало несколько месяцев, количество значений CL стабильно растет. Значительная часть заказов будет в итоге отменена, поэтому значение СА в итоге также будет встречаться в большом списке заказов. Однако если бизнес идет хорошо и заказы продолжают поступать, то количество открытых заказов будет оставаться умеренным и стабильным, даже если данные будут накапливаться годами. Скоро условие Status Code= OP станет достаточно селективным, чтобы предпочесть соединение соответствующих таблиц, даже если столбец Status Code не индексирован, и важно, чтобы оптимизатор мог понять этот факт, лучше - без ручной настройки. Для этого в SQL в условии нужно явно указать необходимое значение, а не использовать общую хранимую процедуру, которая просто выдает константу после разбора, во время вьшолнения. Изменение запроса Чаще всего следует настраивать SQL Server, используя подсказки. Подсказки обьи-но указываются в разделе FROM, где воздействуют на доступ к определенной таблице, или в операторе SQL Server OPTION () в самом конце запроса. Далее перечислены наиболее распространенные подсказки. WITH (INDEX (<№я шдекса>)). Эта подсказка должна находиться сразу же за псевдонимом таблицы в разделе FROM. Она заставляет SQL Server использовать для доступа к этому псевдониму таблицы указанный индекс. Поддерживается также старый синтаксис, ШОЕХ=<Имя инденсд>, но в будущем от него могут отказаться, поэтому я не рекомендую использовать его. Еще более устаревшим и опасным является пока что поддерживаемый метод указания внутреннего идентификатора объекта, соответствующего желаемому индексу. Указание индекса при помоши идентификатора очень ненадежно, поскольку индекс получит новый идентификатор, если кто-нибудь удалит и заново создаст его или если приложение будет перенесено в новую базу данных SQL Server.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |