|
Программирование >> Полное сканирование таблицы
При сравнении узлов во время выбора более поздних соединений рассматривайте значения 1 - R, где R - это коэффициент фильтрации каждого узла В этом контексте значения ОД и 0,0001 близки. Хотя они различаются в 1000 раз, значения 1 - R отличаются лишь на 10 %, и соотношение преимущества и стоимости (см. первое правило в этом списке) будет говорить в пользу менее селективного фильтра, если соответствующий узел намного меньще. ПРИМЕЧАНИЕ Если у вас есть коэффициент фильтрации 0,0001, то вы, вероятно, уже используете этот узел в качестве ведущей таблицы, кроме редкого случая, когда в этом запросе у вас есть два независимых, сверхселективных условия. На рис. 6.30 показан первый пример с близкими значениями, который может заставить вас пойти против простых исходных эвристических правил. Попробуйте решить проблему самостоятельно перед тем, как читать дальше. Aia4 А2аз t t BIOS В2а2 ВЗ 2000 0104 Рис. 6.30. Случай, когда нужно рассмотреть исключения из простых правил При выборе ведущего узла не стоит идти против правил. Коэффициент фильтрации для М намного лучше с точки зрения выбора ведущей таблицы. Затем возникает проблема выбора между А1 и А2, и в обычном случае вы предпочтете более низкий коэффициент фильтрации для А2. Посмотрев на детальные коэффициенты соединения от А1 к М и от А2 к М, вы видите, что из А1 и А2 возвращается одинаковое количество строк, поэтому нет причин делать выбор на основе размера. Однако если вы посмотрите на узлы ниже этих, то увидите, что А1 обеспечивает доступ к двум узлам, которые выглядят еще лучше, чем А2. Нужно попытаться вставить их в план как можно раньше, поэтому вы слегка выиграете, если выберете А1 первым. После того как А1 стала второй таблицей в порядке соединения, выбор третьей очевиден: В2 намного меньше и лучше фильтруется, чем А2. ПРИМЕЧАНИЕ- Если бы под А1 не было узла, очевидно говорящего в пользу присоединения его перед А2, то узлы под А1 никак не влияли бы на выбор между А1 и А2! Таким образом, порядок соединения - (М. А1. 82). Выбор следующей таблицы менее очевиден. Коэффициент фильтрации у С1 немного хуже, чем у А2, но первая таблица намного меньше, в 300 х 2000 раз, поэтому стоимость одной ее строки определенно достаточно низка, чтобы поместить эту таблицу перед А2. Теперь порядок соединения (М. А1. В2, С1), а следующие допустимые узлы - это 81 и А2. Для этих узлов значения (1 - R) равны, соответственно, 0,5 и 0,7, и 81 вдвое меньше А2, что делает ожидаемую стоимость строки из 81 немного меньше. Если бы 81 находилась на грани необходимости добавления нового уровня в ее индекс по первичному ключу, у А2, вероятно, был бы дополнительный индексный уровень, и тогда 81 была бы лучшим выбором. Так как каждый уровень увеличивает объем приблизительно в 300 раз, маловероятно, что индекс будет настолько близок к границе, что различие в размерах в 2 раза сыграет существенную роль. То есть маловероятно, что небольшое различие в размерах может значить достаточно много, чтобы отвергнуть простые правила, основанные на коэффициенте фильтрации. Даже если 81 будет лучше, чем А2, в данной точке плана выполнения это не сыграет большой роли - строки всех четырех уже соединенных таблиц эффективно фильтровались. Так, стоимость последних соединений таблиц будет минимальна, независимо от выбора, по сравнению со стоимостью предыдущих соединений. Таким образом, выберите полный порядок соединения - (М. А1. 82. С1. А2. 81. 83). Теперь рассмотрим задачу на рис. 6.31. Попытайтесь решить ее самостоятельно. М 0.05 А10.4 А20.3 BIOS В2а2 2000 ▼ ciai Рис 6.31. Еще один случай, когда нужно рассмотреть исключения из простых правил Этот случай выглядит практически так же, как и предьщущий, но фильтр для М не настолько хорош, а фильтры в ветви А1 в целом лучше. Фильтр для М в два раза лучше фильтра следующей наилучшей таблицы, С1, но у С1 другие преимущества - существенно меньший размер (в 2000 х 300 х 10, или 6 ООО ООО раз), и она близка к другим фильтрам, обеспечивая чистый дополнительный фильтр 0,2 х 0,4 х 0,5 = 0,04. Если скомбинировать все фильтры в ветви А1, то вы найдете, что чистый коэффициент фильтрации равен 0,04 х 0,1 = 0,004 - более чем в 10 раз лучше, чем тот же коэффициент фильтрации для М. Смысл выбора ведущей таблицы с наименьшим коэффициентом фильтрации состоит в том, чтобы не считывать строк больше, чем крохотная часть самой большой таблицы (обычно корневой), так как стоимость считывания строк из самой большой таблицы обычно и определяет стоимость запроса. Однако здесь вы видите, что база данных считает всего лишь 8 % строк из М, если начнет с ветви А1, вместо того, чтобы начать непосредственно с фильтрации М. Поэтому С1 - это лучшая ведущая таблица. Отсюда, следуя обычным правилам, вы найдете полный порядок соединения как (С1. В2. А1. В1. М. А2. ВЗ). Все эти исключения из правил выглядят запутанными и сложными, я знаю, но не позволяйте им сбить вас с пути или разочаровать! Я добавляю исключения, чтобы полностью изложить теорию и описать некоторые редкие особые случаи, и вы встретитесь с ними максимум несколько раз в жизни. Вы практически всегда будете прекрасно работать, намного лучше, чем остальные, если будете применять простые правила, перечисленные в начале главы. В редких случаях вы можете обнаружить, что результат недостаточно хорош, и тогда, если ставки достаточно высоки, можете рассмотреть вопрос о применении этих исключений. Случаи, когда нужно выбрать соединения хэшированием Когда хорошо оптимизированный запрос возвращает умеренное количество строк, практически невозможно при помощи соединения хэшированием добиться существенного улучшения по сравнению с вложенными циклами. Однако в редких случаях большой запрос может получить заметные преимущества от соединений хэшированием, особенно от соединений с небольшими и хорошо фильтрованными таблицами. Если вы начинаете с таблицы, отфильтрованной лучше остальных в запросе, любое соединение вверх, от главной к детальной таблице, унаследует селективность ведущего фильтра и всех остальных фильтров, которые встретятся к этому моменту в порядке соединения. Например, рассмотрим рис. 6.32. Следуя обычным правилам, начните с А1 с коэффициентом фильтрации 0,001, и выполните два соединения вниз, используя остальные фильтры, равные 0,3 и 0,5, для В1 и В2, соответственно. Следующее соединение с детальной таблицей, М, обычно происходит через индекс по внешнему ключу, который указывает на А1, причем доля нужных строк составит 0,00015 (0,001 x 0,3 x 0,5). Если детальная таблица достаточно большая, чтобы иметь значение для работы приложения, а запрос не возвращает большого количества строк, эта стратегия праетически гарантирует, что вложенные циклы по внешним ключам по направлению к детальным таблицам будут наилучшим выбором. Другие методы соединения, например соединение хэшированием, которое обращается к детальной таблице независимо, через собственный фильтр, считают большую долю строк той же таблицы, так как лучший вариант (с вложенными циклами) начинает работу с лучшего коэффициента фильтрации в запросе. ПРИМЕЧАНИЕ- Единственный редкий случай, в котором соединение с детальной таблицей при помощи хэширования хотя бы немного оправдывает себя, возникает, когда кумулятивное произведение фильтров (произведение уже обработанных коэффициентов фильтрации) перед детальным соединением лежит в том диапазоне, в котором вы могли бы предпочесть полное сканирование детальной таблицы. Этот случай обычно подразумевает или плохо отфильтрованный запрос, возвращающий больше строк, чем нужно, если только таблицы не настолько малы, что оптимизация не играет роли, или редкий запрос с множеством плохих фильтров в различных ветвях под детальной таблицей.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |