Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Тоу Д. -> "Настройка SQL. Для профессионалов" -> 101

Настройка SQL. Для профессионалов - Тоу Д.

Тоу Д. Настройка SQL. Для профессионалов — СПб.: Питер, 2004. — 333 c.
ISBN 5-94723-959-0
Скачать (прямая ссылка): nastroykasqldlyaprof2004.djvu
Предыдущая << 1 .. 95 96 97 98 99 100 < 101 > 102 103 104 105 106 107 .. 161 >> Следующая


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

Существует особый случай, когда таблицы с отношением «один к одному», обозначенные как Т2 и ТЗ, являются одной и той же таблицей. В этом случае каждая строка из Tl соединяется с одной и той же строкой из Т2 дважды. Это абсолютно неэффективно. Очевидный случай, когда одно имя таблицы дважды повторяется в разделе FROM и ему назначаются псевдонимы Т2 и ТЗ, маловероятен, исключительно потому, что он слишком очевиден, чтобы остаться незамеченным. Однако соединение с одной таблицей дважды может произойти незаметно, и быть пропущенным разработчиком при просмотре кода. Например, это может случиться, если синоним или простое представление скрывают сущность основной таблицы, по меньшей мере, за одним псевдонимом в запросе. В любом случае лучше всего избавиться от лишней ссылки на таблицу в запросе и перенести в оставшийся псевдоним все ссылки на столбцы и дальнейшие соединения вниз.

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

На рис. 7.3 показан второй из основных случаев циклических соединений. Здесь идентичные внешние ключи в Tl и Т2 указывают на одно и то же значение первичного ключа в ТЗ.

В этом случае S QL-код выглядит следующим образом:

SELECT ...

FROM ...Tl. ... Т2. ... ТЗ. ...

WHERE ... Tl.FKeyl = Т2.РКеу2 AND Tl.FKey2 = ТЗ.РКеуЗ AND T2.FKey2 = ТЗ.РКеуЗ ...
Необычные диаграммы соединений

205

Рис. 7.3. Циклическое соединение, подразумевающее денормализацию

В этом операторе SQL я назвал внешние ключи, указывающие из Tl на Т2 и ТЗ, FKeyl и FKey2 соответственно. По закону транзитивности значение столбца внешнего ключа Т2. FKey2 равно значению Tl. FKey, так как оба ключа соединяются с ТЗ. РКеуЗ. Первичные ключи Т2 и ТЗ называются РКеу2 и РКеуЗ, соответственно. Самое вероятное объяснение того, что Tl и Т2 соединяются с одной таблицей, ТЗ, по ее полному первичному ключу заключается в том, что Tl и Т2 содержат избыточные внешние ключи, указывающие на эту таблицу. В этом сценарии в столбце FKey2 детальной таблицы Tl содержатся денормализованные данные из ее главной таблицы Т2. Эти данные всегда равны значению FKey2 в соответствующей главной строке таблицы Т2.

ПРИМЕЧАНИЕ -----------------------------------------------------------------------

Предполагается, что значения FKey2 совпадают, но обычно это не так, потому что денормализованные данные чаще всего не синхронизированы.

В главе 10 перечислены аргументы за и против денормализации в подобных случаях. Вкратце, если денормализация оправдывает себя, возможно, что дополнительная связь на диаграмме запроса предоставит вам доступ к лучшему плану исполнения. Однако более вероятно, что денормализация — это ошибка, стоимость и риск которой превосходят преимущества. Отказ от денормализации означает удаление внешнего ключа FKey2 в Tl, таким образом устраняя связь от Tl к ТЗ и превращая диаграмму запроса в дерево.

Случай 3. Двухузловой фильтр (не уникальный на обоих концах) уже связан при помощи обычных соединений

На рис. 7.4 показан третий основной случай циклических соединений. На этот раз у нас есть обычные указывающие вниз стрелки от Tl к Т2 и ТЗ, но также присутствует третье, необычное условие соединения между Т2 и ТЗ, которое не задействует первичного ключа ни одной из двух таблиц.

ПРИМЕЧАНИЕ ----------------------------------------------------------------

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

SQL-код для рис. 7.4 выглядит следующим образом: SELECT ...

FRDM ...Tl. ... Т2. ... ТЗ....

WHERE ... Tl.FKeyl - Т2.РКеу2 AND Tl.FKe>y2 - ТЗ.РКеуЗ

AND Т2.Co!2<Каким-то_образом_сравнивается_с>ТЗ.Col3 ...
206

7. Диаграммное изображение и настройка сложных SQL-запросов

Рис. 7.4. Циклическое соединение с двухузловым фильтром

Например, если Tl—это псевдоним таблицы Orders, которая соединяется с Customers, Т2, и Sal espersons, ТЗ, то это может означать, что запросу требуются заказы, покупатели и ответственные продавцы в которых связаны с разными регионами:

SELECT ...

FROM Orders Tl. Customers T2. Salespersons ТЗ WHERE Tl.Customer_ID = T2.Customer_ID AND Tl.Salesperson_ID = T3.Salesperson_ID AND T2.Region_ID! = T3.Region_ID

Здесь условие T2. Regi on_ID! = ТЗ. Regi on_ID — это, строго говоря, соединение, но лучше рассматривать его как условие фильтрации, которому строки из двух различных таблиц требуются еще до того, как его можно применить. Если вы проигнорируете эту необычную связь между Т2 и ТЗ, то обращение к Tl будет проходить до применения двухузлового фильтра по Region_ID. Единственные порядки соединения, которые избегают непосредственного выполнения необычного соединения между Т2 и ТЗ, это:
Предыдущая << 1 .. 95 96 97 98 99 100 < 101 > 102 103 104 105 106 107 .. 161 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100