|
Программирование >> Полное сканирование таблицы
вас об ошибке в запросе или дизайне. Также вы узнаете, как исправить эти дефекты функциональности или дизайна, иногда одновременно в качестве побочного эффекта улучшая производительность. Обычно исправления позволяют перевести запрос в простую форму или, по крайней мере, в форму, достаточно близкую к простой, чтобы можно было применить методы, описанные ранее в этой книге. Некоторые сложные запросы выходят за пределы любых форм, где используются подзапросы, представления или операции над множествами, например UNION и UNION ALL, диаграммное изображение которых я описывал. Обычно такие сложные запросы полностью функциональны и распространены, поэтому вам потребуется способ создавать для них диаграммы и оптимизировать, для чего нужно расширить предьщущие методы для простых запросов. Необычные диаграммы соединений Если в вашем запросе содержатся только простые таблицы (не представления), нет подзапросов и операций над множествами, таких, как UNION, всегда можно создать определенную диаграмму запроса, применив методы из главы 5. Но иногда диаграмма обладает необычными характеристиками, которые не подходят ни к одному шаблону древовидных соединений, которые я описывал ранее. Я по очереди опишу такие отклонения и объясню, как справиться с каждым из них. Для иллюстрации необычных ситуаций я буду приводить частичные диаграммы запросов, в которых те части диаграммы, которые не существенны для обсуждаемого вопроса, будут за1фыты серыми облаками. Это привлечет внимание к наиболее важной части запроса и сделает пример более обобщенным. В качестве еще одного соглашения я буду рисовать связи с частями скелета соединения, скрытыми за облаками, серым цветом, если они не существенны для текущего обсуждения. Количество серых связей и даже их существование не имеют значения в этих примерах, они просто иллюстрируют потенциальное существование дополнительных соединений в реальных случаях. Иногда к С1фытым частям скелета запроса будут вести связи, окрашенные черным. Существование черных связей важно для обсуждения, но скрытая часть скелета запроса - нет. Графы циклических соединений Как следует обрабатывать скелеты соединений, которые невозможно отобразить на простое дерево, в которых связи в какой-то части скелета замыкаются в цикл? Такая диаграмма может встретиться вам в нескольких случаях. В следующих разделах я рассмотрю четыре случая с различными решениями. ПРИМЕЧАНИЕ - Теория графов - это область математики, которая описывает абстрактные сущности, называемые графами, состоящие из связей и узлов. Используемые в этой книге диаграммы также являются графами. В теории графов в Щ1Клическом графе есть связи, которые форм фуют замкнутый цикл. В следующих примерах, до рис. 7.8, обратите внитние, что на диаграмме есть реальные или подразумеваемые щж-лы, превращающие эти графы в циклические. Случай 1. Две главные таблицы с отношением один к одному совместно используют одну и ту же детальную таблицу На рис. 7.1 показан первый случай, когда единственный внешний ключ соединяется с первичными ключами двух различных главных таблиц. Рис. 7.1. Первый случай циклических диафамм запросов SQL-код для этого случая может выглядеть следующим образом: SELECT ... FROM ...Tl. ... Т2. ... ТЗ. ... WHERE ... Tl.FKeyl - Т2.РКеу2 AND Tl.FKeyl - ТЗ.РКеуЗ AND Т2.РКеу2 = ТЗ.РКеуЗ ... Здесь я назвал единственный внешний 1сяюч таблицы Т1, который указывает на обе таблицы, FKeyl, а первичные 1а1ючи Т2 и ТЗ - РКеу2 и РКеуЗ, соответственно. Если все эти три соединения явно прописаны в SQL, то цгаслические связи очевидны, но обратите внимание, что одна из этих связей могла бы быть пропущена в запросе и отсутствующее условие соединения подразумевалось бы по условию транзитивности (если а = b и b = с, то а=с). Если бы одно из соединений было пропущено, то для того же запроса вы бы создали диаграмму в одной из трех форм, показанных на рис. 7.2. Г2<- т. - ТЗ. тт --i::::;:: - Рис. 7.2. Тот же циклический запрос, на котором одно из условий соединения пропущено Обратите внимание, что в вариантах этого запроса А и В догадаться о существовании отсутствующей стрелки можно на основе того факта, что у связи между Т2 и ТЗ острие стрелки есть на обоих концах, а стрелка на обоих концах подразумевает соединение один к одному . Вариант С, с другой стороны, выглядит как самое простое дерево соединения, и вы бы ни за что не догадались, что в нем присутствует циклическое соединение, если бы не заметили, что Т1 использует один и тот же внешний ключ для соединения с Т2 и с ТЗ. Когда у вас есть таблицы с отношениями один к одному , то циклические соединения, как на рис. 7.1, встречаются часто. Это не функциональная проблема, хотя дальше я перечислю вопросы, которые следует рассмотреть, когда встречается соединение такого типа. Вместо того чтобы рассматривать их как проблему, эти соединения можно считать удачной возможностью для оптимизации запроса. Если вы уже обработали Т1, то полезно иметь выбор - обращаться далее к 12 или ТЗ, так как у какой-то из них может быть лучший коэффициент фильтрации, или же она может предоставить доступ к хорошим фильтрам ниже по дереву. Если вы в порядке соединения обрабатываете Т2 или ТЗ до Т1, то возможность провести соединение вида один к одному с противоположной таблицей (от Т2 к ТЗ или от ТЗ к Т2) также полезна. Это позволяет вам использовать любой фильтр, который может быть у второй таблицы, до соединения с Т1. Без горизонтальной связи вы могли бы соединять Т2 с ТЗ и наоборот только через Т1 - вероятно, с более высокой стоимостью. Некоторые оптимизаторы написаны достаточно хитро, чтобы использовать транзитивность для восстановления отсутствующего условия соединения, даже если оно пропущено, и пользоваться преимуществами дополнительных степеней свободы, предоставляемых порядком соединения. Однако если вы заметили, что два соединения по закону транзитивности подразумевают третье, для надежности лучше сделать все три соединения явными. По крайней мере, в вашем операторе SQL следует сделать явными все соединения, которые требуются для найденного вами оптимального плана. Существует особый случай, когда таблицы с отношением один к одному , обозначенные как Т2 и ТЗ, являются одной и той же таблицей. В этом случае каждая строка из Т1 соединяется с одной и той же строкой из Т2 дважды. Это абсолютно неэффективно. Очевидный случай, когда одно имя таблицы дважды повторяется в разделе FROM и ему назначаются псевдонимы Т2 и ТЗ, маловероятен, исключительно потому, что он слишком очевиден, чтобы остаться незамеченным. Однако соединение с одной таблицей дважды может произойти незаметно, и быть пропущенным разработчиком при просмотре кода. Например, это может случиться, если синоним или простое представление скрывают сущность основной таблицы, по меньшей мере, за одним псевдонимом в запросе. В любом случае лучше всего избавиться от лишней ссылки на таблицу в запросе и перенести в оставшийся псевдоним все ссьшки на столбцы и дальнейшие соединения вниз. Случай 2. В главной и детальной таблицах хранятся копии внешнего ключа, которые указывают на один и тот же первичный ключ третьей таблицы На рис. 7.3 показан второй из основных случаев циклических соединений. Здесь идентичные внешние ключи в Т1 и Т2 указывают на одно и то же значение первичного ключа в ТЗ. В этом случае SQL-код выглядит следующим образом: SELECT ... FROM ...Tl, ...12. ... ТЗ. ... WHERE ... Tl.FKeyl = Т2.РКеу2 AND Tl.FKey2 = ТЗ.РКеуЗ AND T2.FKey2 = ТЗ.РКеуЗ ...
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |