2018-07-13

Delete through index and fullscan

From JL article

It’s not a well-known phenomenon, but Oracle uses a completely
different strategy for deleting through an index range/full scan from
the strategy it uses when deleting through a tablescan or index fast
full scan. For the tablescan/index fast full scan Oracle deletes a row
from the table then updates each index in turn before moving on to
delete the next row. For the index range scan / full scan Oracle
deletes a table row but records the rowid and the key values for each
of the indexes that will need to be updated – then carries on to the
next row without updating any indexes. When the table delete is
complete Oracle sorts all the data that it has accumulated by index,
by key, and uses bulk updates to do delayed maintenance on the
indexes. Since bulk updates result in one undo record and one redo
change vector per block updated (rather than one per row updated) the
number of redo entries can drop dramatically with a corresponding drop
in the redo and undo size.

2018-01-26

Date in dba_audit_trail

timestamp in DBA_AUDIT_TRAIL defined as

cast ((from_tz(ntimestamp#,'00:00') at local) as date)

extended_timestamp defined as

from_tz(ntimestamp#,'00:00') at local

More often you know dates in Database timezone. It’s better to use

extended_timestamp AT TIME ZONE DBTIMEZONE

2018-01-16

Таблица для partition exchange

Комментарий из блога Льюиса

This DDL optimization stuff caused quite a significant headache to our alter table exchange mexhanism, which we had been using for a long time for loading/unloading tables. The first was in 11.1 with the default not null optimization and the second came with 12.1, where oracle optimized even adding column with default value. It is quite tricky to create table for exhange, when the ddl optmization kicks in. For 11.1 feature is is sufficient to force table to be created with proper hakan factor by using event 14529 inside session before CTAS is issues. I’m not sure if it is documented for 12.1 feature now, but to create table with proper hidden columns is possible by setting event 14529, level 512. We were forced to file a SR for this on MOS. It took quite a long untill we received this workarroud.

2017-10-25

Flashback archive grants

You cant find grants for flashback archive tables in DBA_TAB_PRIVS. To determine which users have grants to flashback archives given with

GRANT FLASHBACK ARCHIVE ON SOME_FDA TO SOME_USER;

you have to use query

SELECT u.username, a.*
FROM sys.SYS_FBA_USERS au, dba_users u, dba_flashback_archive a
WHERE u.user_id = au.user#
  AND au.fa# = a.flashback_archive#;

NB: using dba_users is enough, because you can’t grant Flashback archive to role

GRANT FLASHBACK ARCHIVE ON FDA TO FDA_ROLE;
ORA-55625: Cannot grant Flashback Archive privilege to a role

2017-10-02

dbms_metadata necessary privs

  1. Object owner
  2. SELECT_CATALOG_ROLE
  3. SYS
    Otherwise you’ll receive
ORA-31603: object "XXX" of type VIEW not found in schema "AAA"
ORA-06512: at "SYS.DBMS_METADATA", line 5805
ORA-06512: at "SYS.DBMS_METADATA", line 8344
ORA-06512: at line 1

2017-07-12

Косяки Java

1) switch реализован совершенно непонятно. От использования его без break и размещения default не в конце лучше воздержаться.

switch (1) {
    case 2: System.out.print("y");
    case 3: System.out.print("икраткое");
    default: System.out.print("x");
} //вполне ожидаемый х

switch (1) {
    default: System.out.print("x");
    case 2: System.out.print("y");
    case 3: System.out.print("икраткое");
} //внезапное xyикраткое

switch (1) {
    case 2: System.out.print("y");
    default: System.out.print("x");
    case 3: System.out.print("икраткое");
} // печальное xикраткое

Написать case с переменными невозможно – все варианты должны быть разрешены в момент компиляции.

2) Куча запутанных преобразований типов. Но всех переплюнуло уменьшение разрядности – неявное не работает, а явное наоборот, вместо того, что бы выкинуть ошибку сделает большое отрицательное число

int i = Short.MAX_VALUE - 10;
short s = i; //Ошибка компилятора: incompatible types: possible lossy conversion from int to short
short s = (short) (Short.MAX_VALUE + 1);
System.out.print("s=" + s + "; MAX_VALUE+1=" + (Short.MAX_VALUE+1));//s=-32768; MAX_VALUE+1=32768

3) Еще преобразование типов. Приведенный ниже пример конечно не компилируется

short s1 = 0;
short s2 = 1;
short s3 = s1 + s2;
//Error:(6, 15) java: incompatible types: possible lossy conversion from int to short

потому что внезапно

System.out.println(((Object)(s1+s2)).getClass().getName());
//возвращает java.lang.Integer

4) Присваивание это еще и функция, которая возвращает правую часть. Не ошибись в if, не пропусти второе =

boolean b = false;
if (b = true) System.out.print("На самом деле я уже true, посмотри сам " + b);//На самом деле я уже true, посмотри сам true

5) Сравнение строк и StringBuilder – отдельная боль
вот, например, строки одинаковые, а конструкторы вызваны были разные

String s1 = "Я томат";
String s2 = new String("Я томат");
if (s1 == s2)
    System.out.print("По мнению джавы строки '" + s1 + "' и '" + s2 + "' равны");
else
    System.out.print("По мнению джавы строки '" + s1 + "' и '" + s2 + "' НЕ равны");

Рано печалилсь, для StringBuilder это не работает уже из коробки :)

StringBuilder s1 = new StringBuilder("Я томат");
StringBuilder s2 = new StringBuilder("Я томат");

if (s1 == s2)
    System.out.print("По мнению джавы строки '" + s1 + "' и '" + s2 + "' равны");
else
    System.out.print("По мнению джавы строки '" + s1 + "' и '" + s2 + "' НЕ равны");

А вот ударили монтировкой по голове – шнурки развязались

StringBuilder s1 = new StringBuilder("Я томат");
StringBuilder s2 = s1;
s2.append(" очень рад");

if (s1 == s2)
    System.out.print("По мнению джавы строки '" + s1 + "' и '" + s2 + "' равны");
else
    System.out.print("По мнению джавы строки '" + s1 + "' и '" + s2 + "' НЕ равны");
// Мы случайно поменяли и первую строку: По мнению джавы строки 'Я томат очень рад' и 'Я томат очень рад' равны. 

В общем сравнение со строками не совместимо, надо использовать equals

String s1 = "Я томат";
String s2 = " Я томат".trim();
if (s1 == s2)
    System.out.print("По мнению джавы строки '" + s1 + "' и '" + s2 + "' равны");
else
    System.out.print("По мнению джавы строки '" + s1 + "' и '" + s2 + "' НЕ равны");
//С томатами явная проблема: По мнению джавы строки 'Я томат' и 'Я томат' НЕ равны

if (s1.equals(s2))
    System.out.print("По мнению джавы строки '" + s1 + "' и '" + s2 + "' эквальны");
else
    System.out.print("По мнению джавы строки '" + s1 + "' и '" + s2 + "' НЕ эквальны");
//Хоть с эквальностью проблем нету)): По мнению джавы строки 'Я томат' и 'Я томат' эквальны

Но wtf, если вместо строк случайно оказался StringBuilder

StringBuilder s1 = new StringBuilder("Я томат");
StringBuilder s2 = new StringBuilder("Я томат");

if (s1.equals(s2))
    System.out.print("По мнению джавы строки '" + s1 + "' и '" + s2 + "' эквальны");
else
    System.out.print("По мнению джавы строки '" + s1 + "' и '" + s2 + "' НЕ эквальны");
//По мнению джавы строки 'Я томат' и 'Я томат' НЕ эквальны

оказывается разрабочтики метод не реализовали (facepalm)

6) Унарный инкремент и декремент давно пора бы убрать. Польза только в синтаксисе for-цикла, а непонятности вносит много. Вот, например что выведет?

int i = 0;
while (i <= 3) {
    i = i++;
    System.out.println(i);
}

7) Реализация substring по-моему чудовищная, хотя с этих можно смириться.

8) Инициализация переменных. Она зависит от контекста

public class Main {
float gf;
int gi;
public static void main(String[] xxx) {
    int li;
    float lf;
    Main c = new Main();
    System.out.println("Global float default: " + c.gf + "; Global integer default " + c.gi);
    // Global float default: 0.0; Global integer default 0
    System.out.println("Local float default: " + lf + "; Local integer default " + li);
    // не компилируется, т.к. переменные не инициализированы
}
}

9) Игра Угадай-ка

public class Simple {
    public Simple() {/*Угадай, кто из нас конструктор*/}
    public void Simple() {/*Угадай, кто из нас конструктор*/}
    public static void main(String[] args) {}
}

10) Дурацкие типы для литералов

long x = 123;//Компилируется
System.out.println(Integer.MAX_VALUE);//Выводит 2147483647
long x = 2147483999; //не компилируется Error:(6, 10) java: integer number too large: 2147483999
long x = 2147483999L;//Должно быть так

все потому что литерал по-умолчанию имеет тип int

11) “Чудесно” работающая процедура поиска по несортированным массивам

int numbers[] = new int[] {3,2,1};
System.out.println(Arrays.binarySearch(numbers, 2)); //правильное 1
System.out.println(Arrays.binarySearch(numbers, 3)); //странное -4

12) Protected access – вообще отдельная песня. Кажется, что понять скомпилируется код или нет можно уже только постфактум. Примера не привожу ибо длинно и непонятно.

13) Использование пустых ссылок не всегда приводят к ошибкам:

public class Main {
    static int x;
public static void main(String[] xxx) {
    Main m = new Main();
    System.out.println("Static var = " + m.x);//0, инициализирована которым по-умолчанию
    m = null;
    System.out.println("Static var via null link = " + m.x);//и тут 0
}

14) By reference or by value? Или все таки By reference? Вроде как заявляется, что параметры передаются By Value, т.е. изменение параметра внутри функции не влияет на переменную, которая была между скобками в вызывающем коде. Никаких спец конструкций, вроде NOCOPY или by reference в Java нет.
Вот небольшой примерчик:

static void byValueOrByReference(StringBuilder s1, String s2, String s3, String[] many_s) {// а попробуй угадай, что тут по ссылке, а что по значению :)?
    s1.append("но");
    s2 = s1 + "но";
    s3 = s2 + "но";
    for(String s: many_s) {
        s = s + "нейшество";
    }
}

public static void main(String[] xxx) {
    StringBuilder s1 = new StringBuilder("Гов");
    String s2 = "гов";
    String s3 = new String("New гов");
    String[] sarr = {"гов", "нище"};

    byValueOrByReference(s1, s2, s3, sarr);

    System.out.println(s1);//Говно
    System.out.println(s2);//гов
    System.out.println(s3);//New гов -- не смотря на то, что они обещали обычный объект
    System.out.println(sarr[0] + "-" + sarr[1]);//гов-нище
}

Допустим объяснение, что примитивы должны вести себя как-будто их передают по значению, а объекты по ссылке. Но что же со строками, которые объявлены с new и просто? Они по разному вели себя в сравнении, а тут опять выдают себя за примитивы? Непоследовательно как-то…

15) Цепочки периодов работаю немного по разному

public static void main(String[] xxx) {
    LocalDate d = LocalDate.of(2017, 1, 1);

    Period p1 = Period.of(0,0,0);
    p1 = p1.plusYears(1).plusMonths(1).plusDays(1);

    Period p2 = Period.ofYears(1).ofMonths(1).ofDays(1);

    System.out.println(d.plus(p1));//2018-02-02 - как и просили добавился день, месяц и год
    System.out.println(d.plus(p2));//2017-01-02 полнейшая печаль
}

В первом случае создаем пусто период и пользуемся функциями plus* - все работает как часы. А вот во втором, более коротком варианте добавляется только последний вызов. Лучше бы исключение кидали.

16) C StringBuilder.substring нельзя делать цепочки вызовов

StringBuilder s = new StringBuilder("опаньки");
System.out.println(s.insert(0,"ж").substring(0,2).append("пища"));// не компилируется
System.out.println(s.insert(0,"ж").append("пища"));// компилируется

17) Волшебная перезагрузка статических методов, вызов которых работает совсем не так, как в перегружегнных обычных.
В примере ниже: из дочернего объекта вызываем процедуру печати. В первом случае перегруженную, во втором родную.
Процедура печати почти одинаковая – дергает статический и нестатический метод из ?своего? класса. Смотрим на результаты

class Parent {
    static String stat() {return "СТАТИЧЕСКИЙ Parent";}
    String nonStat(){return "Parent";}
    void printInherited(){
        System.out.println("Вызов статической процедуры из Parent вызвал: " + stat());
        System.out.println("Вызов НЕстатической процедуры из Parent вызвал: " + nonStat());
        }
        }
public class Main extends Parent{
    static String stat() {return "СТАТИЧЕСКИЙ Child";}
    String nonStat(){return "Child";}
    void printLocal(){
        System.out.println("Вызов статической процедуры из Child вызвал: " + stat());
        System.out.println("Вызов нестатической процедуры из Child вызвал: " + nonStat());
    }
    public static void main(String... args) {
        Main m = new Main();
        System.out.println("Вызываем процедуру печати из родительского класса. Она наследовалась и не перегружалась");
        m.printInherited();
        System.out.println("Вызываем процедуру печати из дочернего класса");
        m.printLocal();
    }
}
Вызываем процедуру печати из родительского класса. Она наследовалась и не перегружалась
Вызов статической процедуры из Parent вызвал: СТАТИЧЕСКИЙ Parent
Вызов нестатической процедуры из Parent вызвал: Child

Вызываем процедуру печати из дочернего класса
Вызов статической процедуры из Child вызвал: СТАТИЧЕСКИЙ Child
Вызов нестатической процедуры из Child вызвал: Child

Нижняя часть с вызовом для дочернего класса прошла без неожиданностей – обе процедуры дернулись из самого дочернего класса. В верхней части волшебство – поведение то разное. Статический метод вызвался из одного места, а обычный из другого…

18) Немного об абстракных классах и станном компиляторе. Сначала о странном компиляторе: недостижимый код в if(false) и while(false) по-разному недостижимый

Integer i = 1;
Short x = 1;
if(b == x) {System.out.println("Equal");} //Не компилируется, разные типы же
while(false) {System.out.println("False");} //Не компилируется, недостижимый код
if(false){System.out.println("False");} //Компилируется ))

Компилятор на столько умен, что даже запрещает сравнивать переменные разных типов

А что-же он будет делать, когда мы пытаемся объявить и использовать переменную абстрактного класса? (вопрос подчерпнут из тестов для подготовки к экзаменам)

public abstract class Main{
    abstract void calculate();
    public static void main(String[] args) {
        System.out.println("calculating");
        Main x = null;
        x.calculate();
    }
}

Думаете компилятор ругается на создание переменной абстрактного класса (это наверное слишком полезная функциональность)? Хрен, результат прогона такой

calculating
Exception in thread "main" java.lang.NullPointerException
    at Main.main(Main.java:10)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

19) Добавим немного полиморфизма :). Вот переменная и метод, возвращающий эту переменную:

public abstract class Main{
    public static void main(String[] args) {
        A o = new B( );
        System.out.println(o.m1( ) );//20 -- метод вызывается из класса справа от равно и возвращает переменную из класса справа от равно
        System.out.println(o.i ); //10 -- переменная возвращается из класса слева от равно
    }
}

class A { int i = 10;  int m1( ) { return i; } }
class B extends A { int i = 20;  int m1() { return i; } }

20) null…

char[] myCharArr = {'x', 'y'};

 String newStr = null;
 for(char ch : myCharArr){
     newStr = newStr + ch;
     System.out.println(newStr);
 }
Выводит
nullx
nullxy

StringBuilder sb = new StringBuilder("12345");
CharSequence cs = null;
System.out.println(sb.append(cs));//пишет 12345null

no comments

21) Инициализация примитивов и типов-оберток. Говорить о последовательности разработчиков вообще не приходится - тут работает, тут перестало, а тут мы рыбу заворачивали. Ну а инициализация типов-оберток - вообще страшно написана.

//Почти правильная и естественная инициализация. Целочисленные типы без точки, с плавающей точкой через 1.0
double d = 1.0;
float f = 1.0; // из этого блока не работает только это волшебным образом
float f11 = 1.0f; // вот так работает
long l = 1;
int i = 1;
short s = 1;
byte b = 1;
char c = 1;

//неправильная инициализация
double d2 = 1; //это работает
int i2 = 1.0; // а это уже нет

//Инициализация объектов. Конструктор? Какой конструктор?
//И перестал работать Long внезапно
Double d3 = 1.0;
Float f3 = 1.0; //не осилил преобразовать константу
Float f31 = 1.0f;
Long l3 = 1; // Полнейшее рукалицо -- не преобразовал целочисленный в целочисленный
Long l31 = 1L; // Так надо
Integer i3 = 1;
Short s3 = 1;
Byte b3 = 1;
Character c3 = 1;

//неправильная инициализация -- сломалось уже всё
Double d4 = 1; //не работает
Integer i4 = 1.0; //не работает

//Инициализация враперов через конструкторы
//Как всегда непоследовательно -- на этот раз float работает, а вот типы ниже int нет
Double d5 = new Double(1.0);
Float f5 = new Float(1.0);//а про этот в этот раз не забыли -- он работает
Float f51 = new Float(1.0f);
Long l5 = new Long(1);
Integer i5 = new Integer(1);
Short s5 = new Short(1);//забыли написать конструкторы
Short s51 = new Short((short) 1);//надо так
Byte b5 = new Byte(1);//забыли написать конструкторы
Byte b51 = new Byte((byte) 1);//надо так
Character c5 = new Character(1);//забыли написать конструкторы
Character c51 = new Character((char) 1);//надо так
Character c52 = new Character('x');//или так      

To be continued…

dbms_stats.import_table_stats

Если процедура импорта статистики dbms_stats.import_table_stats долго думала и в итоге ничего не сделала, возможно следует проапдейтить колонки C1 (название объекта) и C5 (имя схемы) таблицы статистики
Исследования тут

2017-07-10

Философия performance tuning

Из Expert Oracle SQL: Optimization and Deployment
1. Давать стабильное, предсказуемое, гарантируемое время выполнения повторяющихся запросов. Все изменения в оптимизаторе делают его всё более непредсказуемыми. Тут автор не учитывает генерируемые различными тулами запросы, которые так же должны выполняться быстро
2. Парадокс Dave Ensor: Единственный момент когда безопасно собирать статистику – когда это ничего не изменит. У сбора статистики может быть 2 исхода: ничего не поменяется и мы этим ничего не сломаем или что-то поменяется, но мы не знаем в лучшую или худшую сторону. Это unpredictable, см. пункт первый.
3. Причина, по которой мы собираем статистику в PROD – предотвратить изменение планов запросов, а не убедиться, что они поменяются. Пример – time-based таблицы, в которых без сбора статистики предикаты рано или поздно начнут превышать HIGH_VALUE и Oracle будет ожидать возврат 1 строки. Сбор статистики (а также удаление HIGH_VALUE или, всвязи с указанным автором изменением поведения в 12с, установка HIGH_VALUE в очень большое значение) предотвращает изменение планов.
4. Правильная версия парадокса David Ensor: правильное время для сбора статистики, когда это предотвратит изменение планов
5. Подход Wolfgang Breitling: для того, что бы получить оптимальный план, необходимо и достаточно дать CBO правильные cardinality. CBO будет ошибаться, только если кардинальность различается в несколько порядков
6. Bind variables and histograms should be considered mutually exclusive
7. Средства для стабилизации планов: Outline, SQL Profile (почему-то автор считает, что ошибочно), Baseline
8. Две стороны одной монеты: stability и adaptability. Например в baseline stability это сами baseline, adaptability - возможность планов меняться.
9. TSTATS – запретить планам меняться (stability) без использования каких бы то ни было репозиториев хранения, а корректировкой статистики на таблицах. В основе лежит идея Adrian Billington удаления time-based данных из статистики. Остальные идеи
- сбор статистики на специально сэмулированной тестовой среде с последующим переносом на прод. Такие среды следует использовать для тестирования планов запросов
- Полная генерация статистики для темповых таблиц
- залочить статистику на всех системах для всех объектов
10. Управлять статистикой так же, как и исходным кодом: хранить в SVN, разворачивать вместе с приложением
11. Разные техники хорошо применимы для разных случаев: нужно поправить 1 запрос или несколько запросов. К техникам можно отнести: хинтование, переписывание запроса, физические изменения в базе (параметры, индексы и т.д.) корректировка статистики

2017-07-04

Когда CBO берет информацию из data dictionary

Еще интересный факт всё из той же книги:

Normally, the inputs to the CBO’s estimating process are the object
statistics, system statistics, and initialization parameters. One
exception to this rule is the degree of parallelism specified in the
data dictionary for a table or index. The only other case that I know
of where the CBO uses data dictionary information, other than
statistics, is when it costs full table scans for partitions.

CBO считает стоимость FULL скана к партиции как число блоков / число партиций

2017-07-03

Generate create user statement

BEGIN
dbms_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',true);
END;
/

WITH usr AS ( 
  SELECT ',USER1,USER2,' usr FROM dual
  ),
statements(txt, username, ord) AS (  
  SELECT dbms_metadata.get_ddl('USER', username), username, 1 AS ord
  FROM dba_users u, usr WHERE usr LIKE '%,' || username || ',%'
  UNION ALL
  SELECT dbms_metadata.GET_GRANTED_DDL('ROLE_GRANT', username), username, 2 AS ord
  FROM dba_users u, usr WHERE usr LIKE '%,' || username || ',%' 
    AND EXISTS (SELECT NULL FROM dba_role_privs WHERE grantee = username)
  UNION ALL
  SELECT dbms_metadata.GET_GRANTED_DDL('SYSTEM_GRANT', username), username, 3 AS ord
  FROM dba_users u, usr WHERE usr LIKE '%,' || username || ',%'
   AND EXISTS (SELECT NULL FROM dba_sys_privs WHERE grantee = username)
  UNION ALL
  SELECT dbms_metadata.GET_GRANTED_DDL('OBJECT_GRANT', username), username, 4 AS ord
  FROM dba_users u, usr WHERE usr LIKE '%,' || username || ',%'
   AND EXISTS (SELECT NULL FROM dba_tab_privs WHERE grantee = username)
  )
SELECT txt
FROM statements
ORDER BY username, ord
;

2017-06-14

Hint philosophy

Again from Expert Oracle SQL: Optimization, Deployment, and Statistics

You should be asking yourself these sorts of questions:
• Do I know the reason why I need to hint this code? Why has the CBO picked a different plan to
the one I think is best?
• Do I know that hinting the code will actually make a positive difference, or am I making a
potentially incorrect assumption?
• Are there alternative approaches? Are these alternative approaches better or worse than the
use of hints?
• Do I understand what the hints that I plan to use do?
• Are the hints an appropriate and complete set?
• Will my colleagues understand what I have done and why?

Analytic sorts

If you take a 10032 trace you will see that the ROW_NUMBER analytic function uses what is known as a version 1 sort, which is a memory-intensive, insertion-based sort, whereas the FIRST_VALUE function uses a version 2 sort, which is apparently a fancy combination of a radix sort and a quick sort1 that requires much less memory and fewer comparisons.

From Expert Oracle SQL: Optimization, Deployment, and Statistics

2017-05-31

Prepare POI for Sygic

Sygic doesn’t support POI and routes in standard KML format.
To load POI to Sygic from google mymaps you have to
1. Export layers to KML format (or KMZ format – its just archive with KML plus icons for places). KML is just XML format
2. Process KML file with XSLT transfomation

<!-- longitude | latitude | name | address | phone | fax | web | email | short description | long description -->
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:df="http://www.opengis.net/kml/2.2">
  <xsl:output method="text" encoding="utf-8" />

  <xsl:param name="delim" select="'|'" />
  <xsl:param name="quote" select="'&quot;'" />
  <xsl:param name="break" select="'&#xA;'" />

  <xsl:template match="/">
    <xsl:apply-templates select="df:kml/df:Document/df:Folder/df:Placemark" />
  </xsl:template>

  <xsl:template match="df:Placemark">
    <xsl:value-of select="substring-before(substring-after(normalize-space(df:Point/df:coordinates), ','), ',')"/>|<xsl:value-of select="substring-before(normalize-space(df:Point/df:coordinates), ',')"/>|<xsl:value-of select="normalize-space(df:name)"/>|||||||<xsl:value-of select="normalize-space(df:description)"/>
    <xsl:if test="following-sibling::*">
      <xsl:value-of select="$break" />
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

I did it with Notepad++ text editor with XML Tools plugin

Next steps was taken from Sygic site
3. Download CSV to RUPI converter
4. Process file from step 2 with converter
5. Copy created upi/rupi files to Sygic/maps/import folder (create import folder if you don’t have such)

Unfortunately Sygic support told me, that they have no plans to support KML/KMZ format like free MapsMe do.

2017-05-29

How to read FILTER operation

Из книги Expert Oracle SQL: Optimization, Deployment, and Statistics

if you see a FILTER operation with more than one operand then the
second and subsequent operands (the subquery or subqueries) are
evaluated for each row returned by the first operand (the main query)

Merge and unnest

Опять из книги Expert Oracle SQL: Optimization, Deployment, and Statistics разница между MERGE и UNNEST

• View merging applies to inline views, factored subqueries, and data
dictionary views that appear as row sources in the FROM clause of an
enclosing query block. View merging is controlled by the MERGE and
NO_MERGE hints.

• Subquery unnesting relates to subqueries in the
SELECT list, WHERE clause, or anywhere else that Oracle may in the
future support. Subquery unnesting is controlled by the UNNEST and
NO_UNNEST hints

UNNEST – это про WHERE, SELECT и управляется при помощи UNNEST – NO_UNNEST hints

VIEW MERGING – это про FROM, управляется при помощи MERGE – NO_MERGE hints
Бывает 2 видов:
SIMPLE VIEW MERGING – heuristic transformation, т.е. применяется безусловно, но может быть отменена хинтами.
COMPLEX VIEW MERGING – cost based transformation, применяется, если subquery содержит DISTINCT или GROUP BY.

2017-05-18

Nested loops в планах

NB:

In the case of NESTED LOOPS the estimated row count is per iteration
of the loop whereas the actual row count is for all iterations of the
loop.

Restoring objects statistics

From book Expert Oracle SQL: Optimization, Deployment, and Statistics I found new thing: you don’t need to export-import automatically gathered statistics. Instead of you can use DBMS_STATS.RESTORE* procedures.
By default oracle stores data for 31 days.
Quote from Chapter 9 of the book:

• There are several procedures for restoring statistics including DBMS_STATS.RESTORE_SCHEMA_STATS.
• User statistics set with DBMS_STATS.SET_xxx_STATS procedures are not restored. So, for example, any hand-crafted histogram would have to be reapplied after statistics are restored.
• Although this is normally the default behavior, it is good practice to explicitly invalidate any bad plans in the shared pool by using the NO_INVALIDATE => FALSE parameter setting
• The view DBA_OPTSTAT_OPERATIONS provides a history of gather and restore operations.
• By default superseded statistics are retained for 31 days. This can be managed by the function DBMS_STATS.GET_STATS_HISTORY_RETENTION and the procedure DBMS_STATS.ALTER_STATS_HISTORY_RETENTION.

2017-04-07

Join elimination rules

comment from extremedb here

I found 7 Rules for Join Elimination in last year

1.Primary Key-Foreign Key – normal join, Starting in 10gR2
2.Primary Key-Foreign Key – ANSI join, Starting in 11gR1
3.Primary Key-Foreign Key – (semi/anti) join, Starting in 11gR1
4.Unique Index – outer join, Starting in 11gR1

Every guru knows above 4 things

5.Primary Key-Primary Key – simple self join, Starting in 11gR2 –> you ‘ve aleady mentioned

There are two more things and one simular thing
6.Primary Key-Primary Key – self join filter subsumption, Starting in 11gR2
7.Join Back Elimination – Using Bit Map Join Index, Starting in 9iR1

2017-04-02

Полезное по подсчетам Logical reads

Прочитал у Рендольфа

So here is an important point: If you want to understand the work Oracle has performed in terms of buffer visits you need to consider both, the number of logical I/Os as well as the number of buffers visited without involving logical I/O - this is represented by the “buffer is pinned count” statistics.
Quite often this fact is overlooked and people only focus on the logical I/Os - which is not unreasonable - but misses the point about pinned buffers re-visited without doing logical I/O.
Note that buffer pinning is not possible across fetch calls - if the control is returned to the client the buffers will no longer be kept pinned. This is the explanation why a the “fetchsize” or “arraysize” for bulk fetches can influence the number of logical I/Os required to process a result set.