Тетрадочка DBA

Archive for Июль 2009

Он идет!

Posted by shane54lv на 10 июля, 2009

Не могу не поделиться — выцепил в Сети скудные обрывки фраз

Oracle 12g

Yes, you heard right. Oracle 12g is around the corner. There is not much information available on this new release. The only detail that leaked so far is that Oracle 12g won’t support raw filesystems anymore. This is bad news for RAC environments. The OCR and the voting disk relay on raw filesystems via CFS like OCFS.

The word is that ASM will step in and close the gap in 12g. Also, more emphasis on NFS will be placed as well.

Other than that, there’s not much information regarding functionality enhancements available. As soon as I get more details I will post it.

:)

Posted in Uncategorized | Отмечено: , , | Leave a Comment »

Хозяйке на заметку — SELECT … SAMPLE

Posted by shane54lv на 9 июля, 2009

Навеяно постом Elic‘а из обсуждения «грубый count».

Узнал про интереснейшую фичу в Оракле. Есть возможность указать запросу SELECT прочитать лишь часть таблицы (sample) для того, чтобы получить примерный результат. Это нужно, например, чтобы узнать примерное количество строк в таблице. Если их там миллиард, понятно, что девятьсот миллионов или миллиард сто миллионов — разница не сильно большая, а вот count (*) будет работать сутки. Ну и т.д., примеров как это использовать можно придумать много.

Теория

Тип sample может быть как обычно, строки или блоки. Т.к. sample — это лишь предположение, результат от запроса к запросу всегда будет различаться, но можно заставить базу выдавать всегда одно и то же предположение — SEED.

И последнее. При использовании block sample, запрос обязательно должен идти через FTS или FFS. Если существует другой, более оптимальный путь, Оракл будет использовать его и вместо block sample результат будет выдан на основании row sample. Соответственно, чтобы форсировать block sample, необходимо хинтом указать использование фуллскана (хинт +FULL или +INDEX_FFS).

Практика

Берем таблицу KNS.KNS_LOG:

SELECT ROUND (t1.BYTES / 1024 / 1024 / 1024, 0) AS "Gb"
  FROM dba_segments t1
 WHERE t1.owner = 'KNS' AND t1.segment_name = 'KNS_LOG';

Результат — 28 Гб, самое то :) На продукции count(*) я запускать не стану, но зная количество блоков таблицы и скорость нашей подсистемы I/O (очень приличной, кстати), можно предположить, что работать будет долго. Точнее считать лень, да и не суть.

Теперь магия:

SELECT COUNT (1) * 10000 FROM kns.kns_log SAMPLE BLOCK (0.01);

Пояснение:

  • BLOCK (0.01) — используя блочную выборку, прочитать одну десятитысячную блоков таблицы
  • COUNT (1) * 10000 — соответственно, результат умножаем на десять тысяч

Запрос работает менее пол-секунды, результат 188 190 000. Повторные запуски:


188 190 000
153 360 000
149 630 000
129 950 000
229 950 000

Т.е. результат бросает из стороны в сторону очень значительное, в процентном отношении считать опять таки лень, но на глаз +/- 25%. Хотя это нормально для выборки 0.01% данных!

И последнее. Как я говорил выше, чтобы закрепить какое-то одно значение выборки, используем конструкцию SEED ():

SELECT COUNT (1) * 10000 FROM kns.kns_log SAMPLE BLOCK (0.01) SEED (5);

Число 5 — от балды, берем любую цифру, это просто константа для привязки результата запроса. Результат — 205 800 000 и при повторных выполнениях сохраняется, что и требовалось доказать.

И совсем последнее — проверка правильности результата:

SELECT * FROM dba_tables t1 WHERE t1.owner = 'KNS' AND t1.table_name = 'KNS_LOG';

Значение NUM_ROWS: 198 153 830 (статистика собиралась в воскресенье, два дня назад, после чего в понедельник работал джоб, подтирающий самые старые записи).

SELECT * FROM dba_indexes t1 WHERE t1.owner = 'KNS' AND t1.table_name = 'KNS_LOG';

Значение DISTINCT_KEYS для уникального индекса: 143 667 320.

Т.е. результаты запроса с SAMPLE похожи на правду.

Ссылка на доку: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_10002.htm#i2065953

Posted in Uncategorized | Отмечено: , , , , , , , , | Leave a Comment »