ПредишенСледващото

Между другото, всички които се интересуват от Искам да ви информирам, че днес превод на втората част на книгата Том Кайт "Експерт един-на-един: Oracle" е приключила. Последно досиетата тази сутрин изпраща на издателя.

Как да се произвеждат резултати по страница?

Бих искал да извлича данни след свързването на три маси и сортиране по някакъв област. Тъй като този въпрос се връща около 100 записа, бих искал да се раздели на снимачната площадка резултат на 4 части, всяка от които съдържа 25 записа. И аз бих искал да се изброят записи. Може ли да се направи в SQL * Plus?

Отговор от Том Кайт

В Oracle8i, освободете 8.1 - да.

Това е всичко. В тези преди и включително 8,0 няма да работи.

Прекрасна поискване. Аз просто исках да се уверете, че аз го разбирам. Заявката се изпълнява 4 пъти и всеки път, когато минимален и максимален брой линии се промени. Така ли е?

Отговор от Том Кайт

Да, стойностите на минимални и максимални промени, за да получите различни диапазони на реда.

Ами между?

Да се ​​върнем към стария дебат за разликата между искане

Бих казал, че от гледна точка на производителност, те са идентични. В действителност, плана за изпълнение за първото запитване:

Изглежда по-бързо от

Все пак, имайте предвид, че всички стъпки от плана - не блокират. Така че без значение какво е състоянието се проверява преди.

Отговор от Том Кайт

Моля, не се спори - сложи експерименти и да се докаже (нека, аз винаги правя).

Първата ви разследване ", където ROWNUM между 90 и 100" никога няма да се върне никакви данни. Това състояние - винаги невярно, винаги.

Аз вече доказа, в отговор на друг въпрос (вероятно и ваше), че:

по-бързо от:

Това е всичко, аз се надявам, че ще вкара. Всичко е свързано с процеса на изпълнение на COUNT (STOPKEY) и факта, че ние трябва да направим:

И след това приложите филтъра, докато в първия случай, ние избираме първите 100 линии на всички.

Така че нека да има неопределена маса:

(Това се получава в резултат на трикратния копие от всички all_objects съдържание представяне). Аз ще го направя три искания. Вие да покаже, че той не работи (не се връща на данни), този, който, мисля, че искаш да кажеш, и моята версия:

Сега заявката, която бих ви препоръчваме да:

Голяма разлика. Обзалагам.

Одобрение - те не се нуждаят от никого.
Тестове, експерименти, статистика - аз ги харесвам, аз се нуждаят от тях.

Благодаря ти, Том. Най-накрая забелязах, че в едно условие използване ROWNUM. и в друго - rnum. и че те се различават :-)

Най-доброто решение да дойде с него:

Тя е по-бавен, а е ясно по-малко елегантен :-(

Съжаляваме, но аз не виждам разликата:

Отговор от Том Кайт

Ето какво трябва да се използва.

изпълнява своята заявка, избира първият резултат 100 линии и спирки. Ако VASH_ZAPROS трябва да получите всички редове преди да може да се върне към първата (например, включва тип групата строителство с), разликата в твоя случай може да е малък, но това е. Използвайте TKPROF. да разчиствате време Ryabota на Java код (измерено време на клиента по този начин може значително да наруши резултатите).

Да разгледаме следния пример:

Тук не трябва да отида на последния ред преди да се върне на първия - той работи много "бързо"

Сега нека да добавите функция агрегация - сега ще трябва да се обработват всички редове в таблицата. Въпреки това, тъй като ROWNUM подава, доколкото е възможно, може да ускори работата за сметка на някои оптимизации

И накрая, мислите ли, че - ние не може да устои ROWNUM, доколкото е възможно, не е възможно да се оптимизира нищо, а заявката работи много бавно

В края на краищата, вие решавате. Мога да се показва само, че моята версия работи няколко пъти по-бързо. Изберете.

Във вашия случай, предлагам следното:

  • hz_parties - тази гледна точка (знам)
  • Тази гледна точка polzhno получите всички линии, преди от това ще бъде възможно, за да изберете първия
  • Можете vybiraeet не твърде много линии (около хиляда - всички те се вписват в RAM)
  • Оптимизация на ROWNUM във вашия случай не дава много - като се използва TKPROF можете да разберете какво точно го дава.

Като цяло, аз искам да кажа това:

Използвайки ", където rnum между А и Б" ще бъде грешка, ако можем да вземем ROWNUM във вътрешната заявка и да получите феноменален, като цяло, по-висока производителност. Но сте избрали.

Първата заявка подадена по-ниска бягане два пъти по-бързо от втория. Бихте ли обяснили причината?

Отговор от Том Кайт

Два пъти по-бързо. Странно. Аз не знам какво означава това.

Мога само да кажа, че (след коригиране на вашата заявка), имам различни резултати. В моя случай, когато big_table маса - около 1000000 линии, имам:

Второто искане е по-ефективна от първото.

Отговор от Том Кайт

Ако трябва да изберете да lizhe ontsu, бих посъветвал получаване на резултат, посочен в различен ред, и да изберете по-близо до горната част (за да промените реда на сортиране на данните).

Да, през последните N реда, по принцип, да избират по-дълъг от първия N (не винаги, но това е напълно възможно да се очаква)

Опитах се да се извърши запитване до нареди представителство в който редове са около 7000 eventseverity 64 стойност.

Но резултатът беше само на 234 линии.

Ако се сблъскате с вложено заявка

Получавам 500 линии RNUM със стойности от 1 до 500

Не мога да разбера къде прецака :-( Препоръчайте нещо

Отговор от Том Кайт

Неприятно ми е да си поръчате от подаване на дизайна. Добави за поръчка по заявка. За сложни заявки, не се изисква по реда на данни в подкрепа. Най-вероятно ROWNUM стойност се губи някъде, но не мога да в отсъствието на възпроизводими тестове, за да кажа точно какво се случва.

Внесла искане да ви е много добър и работи бързо в диапазона от 100 000 до 150 000 линии, но когато се опитате да се вземе проба линии след 500 000-та той работи повече от минута.

при извършване на стойностите 150001 и 150010, дава следните резултати и планове

И при извършване на стойностите 1000001 и 1000010 и изхода на плана, са изброени по-долу:

Възможно ли е да се ускори процесът за получаване на последните редове?

Може би е по-добре да се добави ред от DESC дизайн и да се получи на първа страница?

Аз активно използват заявката си при работа с базата данни, като прочетете записите 1000. Ако 100,000 записи (това е съвсем нормално, тъй като потребителите да ми кажете :-)), извадка от първите 1000 линии отнема 50 секунди :-(. (Сървър, работещ на Solaris операционна система и интерфейс JDBC се използва за достъп до базата данни). Трябва да сортирате (ред от) една от основните ключове. може да ви посъветва как да се подобри производителността в този случай.

Отговор от Том Кайт

Използвайте този инструмент (sql_trace + TIMED_STATISTICS) за план за изпълнение на заявки, броят на обработените редове на всяка стъпка от плана, както и въз основа на тези данни, започнете настройка.

Може да се наложи да се извърши оптимизация в FIRST_ROWS режим.

Между другото, поради 1000 линии, - 25 или 100 ще бъдат по-пълно разбрани. Но във всеки случай, най-вероятно ще трябва да се справи всеки път 100,000 линии. Също така проверете размер sort_area размер.

Дали скролируеми курсори (9.2) в PL / SQL и JDBC, или само про C / C ++?

Ако ли не, когато тази функция ще се появи в PL / SQL?

Отговор от Том Кайт

Те са в JDBC.

Аз не мога да си представя ситуация, в която те се нуждаят / искам в PLSQL. Те са полезни за връзки в средата на клиент / сървър, когато искате да видите набор страницата с резултати от по страница, но PLSQL за тази среда не е подходящ - тя работи на сървъра. Предполагаме, че това ще направи на клиента (например формуляри или JDBC). Когато запомнена процедура е необходимо да се "върнете" за обработка на низ?

Как да се възстанови множество п от всяка група на записите от ключ, например за тези данни.

Искам да се върна две записи от всяка група на терена, магазина - два записа за всеки магазин.

Тя ще даде желания резултат.

Реших да разследва допълнително предложения подход вас. И ако някой иска да получи записи с М-тата на N-ти на Департамента вместо Emp:

Е, тази риба може да се опече по различен начин.

Аналитичните функции - това е силата:

Когато се опитате да приложи една от вашите методи имах проблеми.

. Вижте следния код:

Аз решен този проблем, като са извадени искане до линията (OPEN out_cvGenric ЗА "SELECT * FROM.") И определяне на структурата използвате. Всичко работи перфектно.

Защо е тази грешка?

Вижте. Следният код. Това е истинското ми изпълнение на вашия метод в PL / SQL:

Кодът представената по-горе въпрос, подложен на поредица, процедурата се успешно компилиран. Но когато ти се обадя да възникне грешка.

Ако премахнете състояние "tire.tire_date>: ReportFromDt и tire.tire_date <:ReportToDt " из конструкции WHERE. запрос работает нормально и дает результаты. Если в запросе указаны даты, все ломается.

Между другото, това е номерацията на страниците в запомнена процедура значително ще улесни работата на сървъра на приложения. Но, за съжаление, не може да се реши Вторият проблем.

Може ли да предложи решение?

Отговор от Том Кайт

същия проблем и по същия начин на решението в 8и и по-ранни версии - Динамичният SQL или представителство.

2) Защо мислите, че - това е много, много лоша идея. На първо място, отговорът може да се промени, както и промяна (стойността си - само "предполагам"). На второ място, тъй като най-лесният начин да зареждане на системата, за да спре. "О, през цялото време, което правя едно и също нещо, и за толкова дълго време." Това е време, за да се повиши производителността на машината два пъти.

Имате грешка в SQL-декларация. Веднъж видях два проблема:

И ORDER BY - веднага след изразяването и не е достатъчно.

На второ място, не разполагаме с достатъчно двойки се свързват променливи. При използване на списъка - пет променливи, е необходимо да се свързва 7.

Проблемът не е в дати - искането просто погрешно.

Съвет (и открих тези грешки) - копират искане sqlplus. Замяна на заявката глобално '' за 'и да го направя, след като променлива команда:

Сега е ясно, когато повредата.

Pagination при търсенето на най-различни области

Отговор от Том Кайт

VASH_ZAPROS може да бъде формулиран като динамичен SQL.

Всеки път, когато извършвате търсене от asktom на сайта точно това, което е направено. Dynamic, плюс фокуса от ROWNUM.

I - DBA, а понякога се сблъскват с проблеми, свързани с поддръжка на уеб-приложения.

уеб-разработчиците на приложения са ме питали как да се приложи една страница проблем, защото връзката не поддържа информация за състоянието.

Бих искал да изпълни заявката само веднъж, но трябваше да се създаде нещо подобно на следното, което води до повторно разбор, изпълнение и взимане на проби за всяка страница:

1) Доколкото ми е известно, всеки път, когато това се случи ново разглеждане, повторно изпълнение и отново примерни данни. Стойностите на променливи за обвързване се съхраняват и увеличението за всяка страница в заявлението. Това е добър подход?

2) Не е ли по-добре да се върне целия набор (с first_rows оптимизация)?

3) Как да се приложи това?

4) Използване на втория подход, дали да се организира един вид конвейер не могат да бъдат върнати в съответствие приложение е постепенно от един-единствен въпрос, но не и целия набор наведнъж - на масата е твърде висока.

Отговор от Том Кайт

1) Да, аз правя така. Липсва постоянна връзка и работи и в двете клиент-сървър среда, както и какво да правя.

Аз лично за пореден път направи разбор (мека) за всяка страница от ще поддържа отделна физическа връзка (с всички ресурси, като е необходимо) за всеки потребител, в случай, че той иска да види на следващата страница.

2) и ще получите 500 линии, а потребителят гледа първите 10 и никога не отиде на втора страница. Така че сте извършили 50 пъти IO (Lio), от което имате нужда, за да? Най-вероятно, след като в 40 повече от всякога имате нужда (размер straintsy 10 реда, и никога потребител на страница 11 няма да дойде).

4) Това би означавало връщане към архитектурата клиент-сървър, с постоянна връзка, поглъщащ много машинни ресурси, дори и когато те не се използват.

Току-що промених много код, премахване на всички броят на проба (*) преди извършване на действителната заявка - Взех го от бивш разработчик.

Невероятни аргументи, които съм чувал от уеб (PHP) строителя. Току-що промених всичко и даде на потребителите да реши дали те са по-скоро като най-добри резултати, отколкото липса на ненужна информация. Познай какво те избраха!

Това, което липсва, както е редът "Резултати 1-10 от около 500" - би било полезно. Потребителят би искал да знае, ако са останали само няколко записи - тогава трябва да отидете на следващата страница, или има хиляди, така че е най-добре да се уточнят критериите за търсене.

Знам, че Текст компонент Oracle позволява неща за вършене, но е възможно да се измисли нещо в "стандартен" Оракула? За да използвате Oracle Текст трябва да пренапише голяма част от системата.

Може да бъде избран от данните на приложението 21 линия. Ако курсорът се връща записи 10-20, екранът може да бъде издаден ">> поне още 7 реда" (например), както и при връщане на 21-ви издаде ">> поне още 11 реда."


Това, което липсва, както е редът "Резултати 1-10 от около 500"
.

Ако използвате заявки Oracle текст (както аз правя на сайта си), а след това, има съответна функция.

Ако използвате разходно ориентиран оптимизатор 9i сървър, можете да получите приблизителния брой редове, които ще се върнат на искането за представяне срещу $ sql_plan на.

Пейджър, в уеб-среда

По-долу идентификация (спецификация и тялото) пакет posranichnoy дозиране който възнамерявате да използвате уеб-среда. Възможно ли е да се подобри това изпълнение?

Да, човек, нещо, което сте направили погрешно.

а) няма да продължи да се използва променливи за обвързване. Най-добрият начин да съсипеш всяко приложение.

б) Пишеш процесуално код, където само един SQL-оператор.

в) Това процесуално обработката се извършва с един ред.

г) Вие сте поставени в Дън vremennutsyu маса за абсолютно без видима причина.

д) Смятате ли, че общият брой на линии на един - написани в предишния отговор, мисля, че за този подход (аз го направих не е приемливо по принцип).

Ако всичко това е вярно, ние получаваме:

Тя е тази процедура се използва в сайта си?

Ако се свърже променливи в сесията, както и за информация на държавната HTTP-връзка, не се поддържа, както и данните се предават?

Отговор от Том Кайт

Да, това е тази процедура и тя се използва.

Скрити полета, Keys - също работят.

Подкрепете проекта - споделете линка, благодаря!