Ако правите анализ на данни, често трябва да отговаряте на въпроси като:

  • Колко клиенти са посетили нашия уебсайт вчера?
  • Колко различни продукта продадохме миналия месец?
  • Колко уникални SQL оператора е изпълнила базата данни миналата седмица?

Добре, може би последният съм само аз ;)

Във всеки случай често тези въпроси са просто отправна точка за по-нататъшен анализ. Така че просто искате бърза оценка.

Отговорът на тези въпроси обикновено изисква преброяване, различно по следния начин:

select count ( distinct customer_id ) from website_hits;

Но изпълнението на тези заявки може да отнеме много време!

Чакането на отговора е разочароващо. Но е по-лошо, ако получавате цифрите за някой друг. Като шефа си. И те се нуждаят от фигурите за среща. Това започва след минута. И вашата заявка отнема поне десет минути.

Вашият шеф не може да чака толкова дълго. Те се нуждаят от отговор сега!

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

Така че в 12.1.0.2 въведохме approx_count_distinct. Това връща приблизителна оценка за това колко различни стойности има в целевата колона. Това обикновено е над 99% точно и може да бъде значително по-бързо от точните резултати.

Това е яко. Но за да се възползвате от него, трябва да промените кода си! Това може да отнеме много време. Особено защото през повечето време ще искате да можете да превключвате между точни и приблизителни резултати. Така че простото намиране+замяна е налице. Вместо това ще трябва да подадете флаг, за да превключвате между режимите.

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

Така че в 12.2 въведохме нов параметър, approx_for_count_distinct. Задайте това на true така:

alter session set approx_for_count_distinct = true;

и Oracle имплицитно преобразува всички разграничения на броя в приблизителната версия.

Докато играете с това, може да забележите няколко други нови параметъра:

  • приблизително_за_агрегиране
  • приблизително_за_процентил

И така, за какво става въпрос?

Ами в 12.2 създадохме нова функция, approx_percentile. Това е приблизителната версия на функциите percentile_disc и percentile_cont. Това е същата концепция като approx_count_distinct, просто приложена към тези функции.

Синтаксисът за него е:

approx_percentile ( 
  <expression> [ deterministic ], 
  [ ('ERROR_RATE' | 'CONFIDENCE') ] 
) within group ( order by <expression> )

Както можете да видите, това има няколко допълнителни клаузи над approx_count_distinct.

Детерминистичен

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

Сега може би се чудите: „Но защо изобщо бих искал недетерминирани резултати?!“. Е, няколко причини:

  • Недетерминистичните резултати са по-бързи.
  • Можете да получите детерминистични резултати само за числови стойности.

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

Но струва ли си спестяването на време за недетерминистични резултати?

За да разбера, създадох таблица с 16 милиона реда, използвайки Exadata Express Cloud Service. След това сравнява времето на изпълнение на следните точни, детерминистични и недетерминистични процентили:

select percentile_disc(0.1) 
         within group (order by y) 
from   super_massive; 
select approx_percentile(0.1 deterministic) 
         within group (order by y) 
from   super_massive; 
select approx_percentile(0.1) 
         within group (order by y) 
from   super_massive;

Осредняването на времето за три изпълнения на всяко даде следните резултати:

Недетерминистичните резултати са около 5 пъти по-бързи от детерминистичните. И почти 15 пъти по-бързо от точните резултати!

Така че, ако приблизителната стойност е всичко, от което се нуждаете, можете да си спестите много време, като използвате approx_percentile.

ERROR_RATE и CONFIDENCE

Ако получавате приблизителни цифри, възниква въпросът колко точно са резултатите? Ако е 99,9999%, това почти сигурно е „достатъчно добро“. Но какво ще стане, ако те са само 98% точни? Или 95%? В даден момент грешката е твърде голяма, за да разчитате на прогнозата и ще искате да се върнете към точни изчисления.

Но за да направите това, трябва да знаете каква е грешката!

За да намерите това, подайте ERROR_RATE или CONFIDENCE като втори параметър. Тогава ще получите цифрите за точност вместо резултата от функцията. Увереността е колко сме сигурни, че отговорът е правилен. Процентът на грешки дава нивото на неточност.

Идеален за установяване колко добро е приближението.

И има още.

Манияците на статистиката сред вас ще знаят, че медианата е специален случай на процентил. Така че има и налична функция approx_median. Това работи по същия начин като approx_percentile.

Как тези функции са свързани с параметъра approx_for_percentile?

В Oracle има две процентилни функции, percentile_disc и percentile_cont. Така че имате опции да конвертирате едно от тези или и двете. И дали да го направим по детерминистичен начин или не. Стойностите, които това приема, са:

  • всички детерминистични
  • процентил_диск детерминиран
  • percentile_cont детерминиран
  • всичко
  • процентил_диск
  • процентил_продължение
  • нито един

Пълната статия е публикувана първоначално в blogs.oracle.com на 10 ноември 2016 г.