Недавно я написал сложный оператор SELECT (на основе многих очень, очень сложных представлений), выполнение которого займет 1 час 50 минут при запуске из Toad на моем рабочем столе и всего на несколько минут быстрее при запуске из сценария Python с использованием cx_Oracle. библиотека (записывается на диск каждые 50 строк). Общий размер единственного набора результатов составлял около 8000 строк общим размером 5 МБ. Во время выполнения моя рабочая станция не перегружалась, и загрузка процессора была достаточно низкой.
Тот же самый запрос, выполненный на сервере, занял поразительную 21 секунду, чтобы создать побайтный идентичный набор результатов. Это также было создано тем же скриптом Python / cx_Oracle.
Передача 5-мегабайтного файла набора результатов с сервера на мою рабочую станцию заняла всего 3 секунды, поэтому я не думаю, что пропускная способность сети является прямой проблемой.
Может ли SQL * Net или одна из связанных с ним библиотек быть виноватыми? Возникают ли проблемы с нелинейным управлением памятью при вызове запросов по сети? Набор результатов размером 5 МБ - большой, но не слишком большой в наши дни. Есть ли какие-нибудь настройки конфигурации размера буфера, которые могут помочь? Я использую ванильную установку клиента Oracle.
Рабочая станция - Windows XP Pro SP3 (всего 1 ГБ ОЗУ) с клиентом Oracle 10g и Toad для Oracle Xpert 9.7.2.5 и Python 2.6.2 с cx_Oracle 5.0.2. Сервер - Red Hat 2.6.9-67.ELsmp на четырехъядерном сервере Xeon 3,8 ГГц 8 ГБ, работающий под управлением Oracle 10.2.0.4, Python 2.3.4, cx_Oracle 4.4.1.
Изменить: Упс! Файл был только 5 мегабайт, а не ГБ. Очень жаль.
Решено: перед упомянутым мной запросом на извлечение выполнялся сценарий заполнения. После повторного запуска этого сценария заполнения запрос на извлечение выполнялся в течение 2 часов независимо от расположения клиентской программы. После этого первого длительного прогона набор результатов должен был быть где-то кэширован, и я не заметил этого эффекта, пока методично не перебрал все комбинации.
Проследите выполнение в Oracle, и, возможно, вы увидите, что ваша рабочая станция извлекает небольшие фрагменты данных и быстро увеличивает задержку.
Решением может быть массовое получение результатов, как здесь:
Разрешение разногласий Oracle в TOAD; посмотрите на мир жаб, ищите
http://www.toadworld.com/Experts/GuyHarrisonsImprovingOraclePerformance/ResolvingOracleContention/May2008OracleNetworkContention/tabid/374/Default.aspx
(извините, не могу добавить гиперссылки)
Я не очень хорошо знаком с Oracle, но предыдущий опыт работы с сетевыми протоколами для других баз данных показал мне, что они полностью игнорируют проблемы с задержкой. Другими словами, даже если нет слишком большого количество данных для передачи, все еще может стать ледяным, если вам придется сделать несколько циклов к серверу для каждого значения.
Вы можете проверить эту теорию, если добавите немного задержки в свою сеть (я знаю, что это возможно в Linux, я могу только представить, что есть какой-то способ сделать это в Windows) и посмотрите, значительно ли это влияет на общее время выполнения.
Другой вариант заключается в том, что часть обработки может выполняться на стороне клиента, которая может передавать гораздо более 5 ГБ промежуточных данных для получения результата. Это, вероятно, проявится как довольно заметная нагрузка на ваш рабочий стол, так что это не так уж вероятно.
Следует учитывать два момента:
Вы выполнили запрос сначала в Toad, а затем в python + cx_Oracle? В первый раз, когда вы выполняете запрос, Oracle необходимо проанализировать запрос, создать план выполнения и выполнить план: прочитать с диска в память (буферный кеш), выполнить соединения и т. Д. ... Во второй раз Oracle использует тот же план выполнения (хранится в SGA) и читает из буферного кеша, а не с диска. Второй раз, когда вы выполняете тот же запрос, может быть намного меньше времени.
Загрузка 8000 строк / 5 ГБ данных (655 Кбайт на строку !!!) в TOAD для отображения их в графическом интерфейсе может занять много времени. С python + cx_Oracle вы ничего не отображаете, поэтому здесь вы экономите много времени.
ИЗМЕНЕНО: Хорошо, поэтому 8000 строк / 5 Мб данных (655 байт на строку) не должны быть проблемой для отображения TOAD.
Все признаки указывают на узкое место в сети. Какую пропускную способность вы получаете при передаче файлов между этими двумя компьютерами? Можете ли вы попробовать выполнить тот же запрос с другого компьютера, но более близкого по топологии сети?
Эффективная скорость передачи составляет 6,2 Мбит / с - совсем не очень хорошо. Это снимок в темноте, но ... вы забываете сообщить нам, что между вашей рабочей станцией и сервером есть кабельный модем? :)
Возможно, ваша рабочая станция гирляндно подключена к IP-телефону, и вы действительно подключены на скорости 10 Мбит / с?
Извините, если я констатирую очевидное, но вы не упомянули конфигурацию вашей сети в своем вопросе.
Один оператор SELECT должен быть полностью отправлен на сервер для анализа и выполнения. Клиент сам решает, как будут возвращены эти результаты. Готов поспорить, что проблема заключается в том, как ваши клиенты получают результаты. Прошло много времени с тех пор, как я использовал TOAD, поэтому я не знаю, выполняет ли он массовую выборку данных, но это единственное место, где вы можете значительно улучшить скорость, как отмечает @slovon.
Просто для улыбки, посмотрите, какие отчеты traceroute отправляются с вашей рабочей станции на сервер и наоборот.
РЕДАКТИРОВАТЬ: еще одна вещь, которую можно попробовать, - запустить ваш скрипт python на сервере, но пройти через соединение TNS через прослушиватель на сервере. Это должно дать вам представление о том, какое влияние программное обеспечение TNS оказывает на ваш запрос, устраняя при этом любые промежуточные сетевые проблемы.
Кроме того, убедитесь, что ваш DNS исправен (должен иметь возможность выполнять обратный поиск) и что вы не используете DHCP на сервере. Подчеркивание в имени хоста тоже недопустимо.
Получите трассировку с указанием времени ожидания на сеансах как от TOAD, так и локально. Затем сравните события ожидания и время, а также план выполнения. Возможно, план другой.