|
Программирование >> Полное сканирование таблицы
Случай 1. Отсутствующее условие соединения Чаще всего присутствие второго корневого узла указывает на некоторое отсутствующее условие соединения, которое превратило бы один из корневых узлов в главный узел. На рис. 7.11 показано это преобразование, когда соединение от Master к Rootl превращается в соединение один к одному путем добавления некоторого дополнительного условия для Rootl (переименованного в R1), которое гарантирует, что база данных найдет для каждой строки из Master максимум одну строку в R1. Это особенно вероятно, когда в R1 хранятся некоторые детализированные данные, зависящие от интервалов времени (например, различные налоговые ставки), соответствующие главной записи (например, налоговой сущности), а добавление условия по дате (например, запрос текущей на7ЮГОвой ставки) превращает соединение в один к одному . Root2 ---- i- Рис. 7.11. Исправление запроса с несколькими корневыми узлами Часто условие, превращающее соединение в один к одному , уже присутствует, и вы обнаруживаете, что комбинация соединения вида многие к одному и обманчивого фильтра просто отменяет детальный коэффициент фильтрации. ПРИМЕЧАНИЕ В этом примере коэффициент фильтрации для такого фильтра был бы равен 0,2, а детальный коэффициент соединения с Rootl - 5. Иначе условие, превращающее соединение в один к одному может просто отсутствовать в запросе, особенно, если разработка проводилась в тестовой системе, где отношение один ко многим было скрыто. ПРИМЕЧАНИЕ Это иллюстрирует предыдущий пример различных налоговых ставок. В среде разработки могут присутствовать записи только для текущей ставки, скрываюи1ие ошибку потери условия по дате для таблицы ставок. Потеряно ли условие, которое превращает соединение в один к одному , или просто не очевидно, что оно связано с соединением, но вы должны включить это условие и распознать его как часть соединения, а не как независимое условие фильтрации. Такое отсутствующее условие соединения особенно вероятно, когда вы обнаруживаете, что внешний ключ для одной из корневых таблиц, указывающий вниз на общую главную таблицу, также является частью составного первичного ключа этой корневой таблицы. Случай 2. Разбивка декартова произведения на несколько запросов На рис. 7.12 показано другое решение задачи с диаграммой запроса с несколькими корневыми узлами. Это решение сродни явному выполнению отдельных запросов на несвязной диаграмме запроса. Оно заключается в том, чтобы разбить декартово произведение и заменить его двумя отдельными наборами. В этом примере мы заменяем запрос, который вернул бы по 150 строк для каждой строки из Master, на два запроса, которые совместно вернут по 35 строк для каждой строки из Master. Если вы видите отношение один ко многим главной таблицы с двумя различными корневыми детальными таблицами, то можете получить в точности те же данные, считав намного меньше строк раздельными запросами, как показано на рисунке. Поскольку результаты примут немного другую форму, вам также потребуется изменить логику приложения, чтобы обработать данные в новой форме. Rootl Root2 Рис. 7.12. Исправление декартова произведения за счет отдельных запросов Случай 3. Отношения с корневыми детальными таблицами не более чем один к одному На рис. 7.13 показан случай диаграммы с несколькими корнями, когда производительность исходного запроса не представляет проблемы. Так как детальный коэффициент соединения Master с Rootl равен 0,5, декартово произведение не приводит к резкому увеличению количества строк в декартовом произведении, когда вы ком- бинируете подходящие записи из Rootl и Root2 для средней подходящей записи из Master. Можно считать соединение с Rootl соединением вниз и даже отдавать ему предпочтение, как если бы оно улучшало в 0,5 раз коэффициент фильтрации для фильтрующего соединения, следуя правилам из главы б для специальных случаев (в данном случае для детальных коэффициентов фильтрации, меньших 1,0). Rootl Root2 Рис. 7.13. Декартово произведение с небольшим детальным коэффициентом соединения Хотя этот запрос не является проблемой для настройки, он все же может быть неверным. Соединение вида один к нулю или один ко многим от Master к Rootl, очевидно, обычно превращается в один к нулю или один к одному , обеспечивая безопасное декартово произведение. Но так как соединение в редких случаях все же может превращаться в один ко многим , необходимо учитывать, что результат может возвратить декартово произведение с повторениями для данной строки из Root2. Поскольку такой случай редок, вероятнее всего, запрос в действительности разрабатывался и тестировался, чтобы возвращать результаты, однозначно отображающиеся на строки из Root2 ( один к одному ), а приложение во всех прочих, редких случаях может вовсе не работать. ВНИМАНИЕ - Чем менее вероятна ситуация один ко многим , тем более вероятно, что этот случай упущен в дизайне приложения. Например, если приложение изменит данные Root2 после считывания их из таблицы этим запросом и попытается отправить изменения обратно в базу данных, то ему необходимо будет решить, какую копию повторяющейся строки Root2 следует отправить. Должно ли приложение предупреждать конечного пользователя, что произошла попытка отправить противоречивые копии? Если приложение собирает данные Root2 при помощи запроса, избегает ли оно добавления данных из повторяющихся строк Root2? Случай 4. Преобразование проверки существования в явный подзапрос Одно из решений функциональной задачи на рис. 7.13 уже показано на рис. 7.12. Один запрос просто разбивался на два подзапроса. Другое решение, которое часто бывает лучшим, позволяет изолировать ветвь с Rootl в подзапросе, обычно с условием EXISTS. Это решение особенно хорошо работает, если исходный запрос не выбирает столбцы из Recti (или из любых таблиц, присоединенных ниже при помощи скрытых серых связей на рис. 7.13). В этом относительно часто встречающемся специфическом случае вас в действительности интересует только, существует ли
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |