2020-03-19

Why my windows stops sleeping?

Why windows exit from sleep or hibernate mode? I’ve spent a lot of time trying to find answer on this question in internet. And finally found solution. Run from cmd with Administrator privileges

C:\Windows\system32>powercfg -sleepstudy

Sleep Study report saved to file path C:\Windows\system32\sleepstudy-report.html.

and see the report. This’ll show the reason why system enters/exits sleep/hibernate mode.

2020-02-19

Java: collections to array

From habr:

С конвертацией коллекций в массивы у Java была непростая история. С момента появления Collection в Java 1.2 было два способа создания массива на основе коллекции:

  • Использовать метод [Collection.toArray()](https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/util/Collection.html#toArray()), который возвращает Object[].
  • Использовать метод Collection.toArray(Object[]), который принимает уже созданный массив и заполняет его. Если переданный массив недостаточной длины, то создаётся новый массив нужной длины того же типа и возвращается. С появлением дженериков в Java 1.5 метод логичным образом поменял свою сигнатуру на [Collection.toArray(T[])](https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/util/Collection.html#toArray(T%5B%5D)).

Загвоздка в том, что если нужен массив конкретного типа (допустим String[]), второй метод можно использовать двумя способами:

  • Использовать конструкцию collection.toArray(new String[0]). Тем самым, мы сознательно почти всегда отбрасываем массив, а передаём его туда, чтобы метод узнал тип массива.
  • Использовать конструкцию collection.toArray(new String[collection.size()]). В этом случае массив передаётся нужной длины, а значит ничего зря не отбрасывается, и код по идее работает быстрее. К тому же здесь не нужен рефлективный вызов.

Таким образом, второй вариант долгое время считался основным, и в IntelliJ IDEA даже была инспекция, которая подсвечивала первый вариант и предлагала конвертировать его во второй, более эффективный.

Однако в 2016 году вышла статья Алексея Шипилёва, где он решил досконально разобраться в этом вопросе и пришёл к выводу, что не-а: первый вариант всё-таки быстрее (по крайней мере в версиях JDK 6+). Эта статья получила большой резонанс, и в IDEA решили изменить инспекцию, сделав у неё три опции: предпочитать пустой массив (default), предпочитать преаллоцированный массив или предпочитать то или иное в зависимости от версии Java.
tags:

2020-02-17

Coupling and cohension

Quote from habr

Принцип единственной ответственности возник как попытка объединения двух важных понятий структурного анализа и проектирования: coupling (сопряжение, зацепление, связанность) и cohesion (сплочённость, связность, прочность модуля).

Как это было

Модуль A связан с модулем B, или что тоже самое, модуль B связан с модулем А, только тогда когда существует передача информации между ними.

Модуль A зависит от модуля B, а модуль B не зависит от A, если изменения в спецификации А никогда не приведут к изменениям кода в B, а изменения в спецификации B могут приводить к изменениям кода в A.

Существует также альтернативная формулировка:

Модуль A зависит от модуля B, а модуль B не зависит от A, если удаление модуля B приводит к нарушениям в работе A.

2019-05-22

More than 1000 elements in IN clause

All solutions are well-known:

-- 1. The most elegant
WHERE ('fake', val) IN (
  ('fake', val1),
  ('fake', val2),
  ('fake', val3),  
  ...
); 
-- 2. The most obvious
val IN (
SELECT val1 FROM dual UNION ALL
SELECT val2 FROM dual UNION ALL
SELECT val3 FROM dual UNION ALL
...
) 
-- 3. XMLTable magic
val IN (SELECT trim(COLUMN_VALUE) FROM XMLTABLE('"val1","val2","val3",...')) 

I just want to mention one thing about XMLTable solution: string parameter for this function can exceed 4000 symbols (checked in Oracle 11.2.0.4)

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.