|
Программирование >> Полное сканирование таблицы
С другой стороны, если выполняется доступ к диапазону значений, например, Retirenient Date BETWEEN 2002/01/01 and 2003/01/01, то вы обнаружите целую последовательность отсортированных списков идентификаторов строк для каждой даты из диапазона. Движение считывающей головки диска будет менее упорядоченным и, следовательно, менее эффективным. Самокэширование в этом случае может вовсе не произойти, если время выполнения запроса превышает срок жизни блоков в кэше. Даже если вы введете условие равенства, то, возможно, получите именно этот менее эффективный вариант в случае, когда индекс состоит из нескольких столбцов. Например, Last Name- Smi th - это в действительности условие на диапазон для индекса (Last Name. Fi rst Narne), так как существует множество пар с различными значениями, удовлетворяющих этому условию для одного столбца. Точные формулы, описывающие компромисс между произюдительностью полного сканирования таблицы и производительностью сканирования диапазона, сложны и не очень полезны, так как вы сможете только попытаться определить наугад необходимые входные данные (например, относительные коэффициенты успешного попадания в кэш для блоков, к которым было произведено обращение при сканировании диапазона и остальных блоков таблицы). Я понимаю, что все это звучит излишне сложно и с этим неудобным диапазоном от 0,5 до 20 % трудно работать, но на практике проблема обработки среднего диапазона становится несложной. Если таблица достаточно большая, и разница между полным сканированием таблицы и индексным доступом к ней будет весьма существенна, лучше выбрать более жесткое условие и использовать индекс. В противном случае может быть возвращено строк больше, чем требуется. Позже я подробно опишу, почему несколько хорошо спроектированных запросов обязательно возвращают существенную часть (до 1 %) большой таблицы. Реальные приложения существуют в основном для того, чтобы предоставить конечным пользователям удобный доступ к данным. Когда пользователи работают с данными в оперативном режиме, им становится неудобно обрабатывать большие объемы данных. Они терпимо относятся к большим объемам данных в отчетах, но и отчет, предоставляющий больше информации, чем пользователь может усвоить, является плохо проработанным. В Главе 10 мы подробно обсудим способы улучшения запросов, возвращающих слишком много строк. Если вы сомневаетесь, использовать ли полное сканирование таблицы или индексный доступ к ней, просто измерьте, сколько времени требует каждый из вариантов. Метод проб и ошибок прекрасно работает, если на выбор у вас лишь пара вариантов. Однако помните, что вариант, который вы протестируете первым, будет в невыгодном положении, если второй будет протестирован сразу же после первого - второй вариант воспользуется блоками, кэшированными во время проверки первого. Обычно я проверяю каждый из вариантов дважды, с минимальным разрывом во времени, и учитываю второе время выполнения, поскольку во второй раз кэширование было идеальным. Если время для обоих вариантов различается несущественно, я повторяю эксперименты с разрывом во времени 10 минут и более, чтобы измерить более реалистичные затраты на физический ввод-вывод, и повторяю первый эксперимент через 10 минут после второго, изучая его воспроизводимость. Не гонитесь за небольшими улучшениями. Если производительность двух вариантов практически одинакова, остановитесь на уже имеющемся плане выполнения. Изменение одного оператора в целях улучшения производительности на несколько процентов не стоит затраченных усилий. При настройке следует добиваться улучшения времени выполнения в два и более раз. Такое улучшение можно произвести на удивление часто, когда производительность запроса настолько низка, что небольшие улучшения приводят к очень хорошему результату. Вычисление селективности При настройке запросов лзчше всего представлять себе однотабличные условия как фильтры. Эти фильтры пропускают строки таблицы, которые требуются приложению (то есть удовлетворяют условиям), одновременно отбрасывая ненужные строки (не удовлетворяюшие условиям). У приложения есть свои функциональные причины, по которым оно ис1слючает ненужные строки из таблицы, но с точки зрения производительности работа фильтра заключается в экономии усилий и времени сервера баз данных. Смысл настройки заключается в том, чтобы избежать любой работы со строками, с самого начала предназначенными на выброс. В селективности заключается мощь фильтра как инструмента исключения строк, выраженная в размере фрагмента таблицы, который фильтр пропускает дальше. База данных может применять фильтры на трех этапах с переменным успехом в деле минимизации стоимости запроса. Определение условия для индексного диапазона. Условия, которые определяют границы сканируемого диапазона индекса, не требуют никакой работы на ненужных строках. Указание строк таблицы, полученных из индекса. Иногда условия не определяют границы индексного диапазона, но, тем не менее, их можно оценить в индексе до осуществления доступа к таблице. Эти условия требуют обращения к строкам, которые в конечном итоге исхсдючаются из результирующего набора, но происходит это в индексе, а не в таблице. Указание строк, возвращенных после доступа к таблице. Если условие требует получения столбцов, содержащихся в таблице, но не в индексе, сервер баз данных не может применить условие до тех пор, пока не считает строки таблицы. Фильтры, которые применяются к таблице, не имеют никакого значения с точки зрения сокращения стоимости обращения к строкам таблицы. Однако они сокращают себестоимость, так как исхслюченные строки возвращать не требуется. Если фильтруемая таблица - не последняя и не единственная, к которой идет обращение, любой фильтр также сокращает стоимость соединений с другими таблицами позднее в плане выполнения. Селективность фильтра В этом разделе я расскажу, как подсчитать селективность условий, накладываемых на таблицу. Начнем с нескольких определений: Селективность фильтра с единственньш условием. Доля строк таблицы, удовлетворяющая единственному условию на эту таблицу. Селективность фильтра с несколькими условиями. Доля строк таблицы, удовлетворяющая комбинации условий, которые относятся только к этой таблице. Независимость фильтров. Предположение, обычно верное, что селективность нескольких условий можно вычислять просто как произведение долей, характеризующих селективности с единственным условием. Например, условие на имя человека и условие на почтовый индекс человека логически независимы. Можно предположить, что доля строк, в которых содержатся подходящие имя и почтовый индекс, будет приблизительна равна произведению доли строк с подходящим именем и доли строк с подходящим индексом. Например, если 1/100 строк содержит желаемое имя и 1/500 строк - желаемый почтовый индекс, то селективность фильтра с несколькими условиями будет равна 1/100 х 1/500 = 1/50 ООО. Избыточность фильтров. Противоположность к независимости фильтров. Истинность одного условия гарантирует истинность другого. Например, условие на почтовый индекс с большой вероятностью гарантирует получение единственного значения телефонного кода области, поэтому селективность обоих условий будет не лучше селективности условия на почтовый индекс. Всегда можно проверить избыточность полного или частичного фильтра, подсчитав селективность фильтра с несколькими условиями с предположением независимости фильтров и посмотрев, равно ли это значение действительной селективности комбинации этих условий. Настраивая запрос и оценивая селективность фильтра, начните с вопроса, является ли запрос одиночным или же он представляет целую группу запросов. Во втором случае задайтесь вопросом о распределении значений внутри группы. Например, рассмотрим запрос: SELECT ... FROM Orders WHERE Unpa1d F1ag=Y: Мы надеемся, что у этого запроса высокая селективность, так как условие будет выполняться для небольшой доли полной истории заказов. Если вы рассчитываете, что при выполнении запроса для Unpaid Fl ад значения Y будут найдены, то, возможно, захотите индексировать этот столбец. Если же этот запрос является частью группы, которая так же часто выполняет поиск с не очень селективным условием Unpaid Flag=N, то лучше будет избежать индексирования. В этом примере значение поля имеет особый смысл в запросе, оно управляет назначением запроса в целом (найти счета, требующие отправки), поэтому вы можете рассчитывать на то, что найдете в основном запросы по Y, которое является редким значением. ПРИМЕЧАНИЕ Да, раньше я обещал, что вам не нужно будет понимать приложение для настройки его SQL. Вы всегда сможете обратиться к разработчикам, если SQL приложения будет постоянно указывать на редкое индексированное значение. Однако вы будете удивлены, когда поймете, насколько много вы можете узнать о приложении, лишь немного подумав, что же составляет его смысл, и зная имена таблиц и столбцов. Обратите внимание, что в примерах список в операторе SELECT я обычно заменяю троеточием. Оказывается, список выбираемых вами столбцов и выражений не имеет особого влияния на производительность запроса, которая в основном зависит от списка таблиц во фразе FROM и условий во фразе WHERE.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |