Найти в Дзене
Oracle Developer

Что такое статистика таблиц и индексов и как она влияет на план запроса

Коллеги, всем привет! С вами Кирилл Михалько. Сегодня поговорим о статистике. Оптимизатор Oracle выбирает план выполнения запроса не наугад - он опирается на статистику. Без актуальной статистики даже идеально написанный SQL может работать в сотни раз медленнее. Сегодня разберём, что это за статистика, где она хранится и почему её нужно регулярно обновлять. Что такое статистика Статистика - это метаданные о таблицах и индексах, которые Oracle собирает и хранит в системных представлениях. Основные метрики: 🔹 NUM_ROWS - количество строк в таблице 🔹 NUM_DISTINCT - количество уникальных значений в столбце 🔹 DENSITY - плотность распределения данных 🔹 LOW_VALUE / HIGH_VALUE - минимальное и максимальное значения 🔹 HISTOGRAM - распределение данных для столбцов с неравномерными значениями 🔹 CLUSTERING_FACTOR - степень упорядоченности данных относительно индекса Эти данные хранятся в представлениях USER_TABLES, USER_TAB_COLUMNS, USER_TAB_STATISTICS, USER_INDEXES, USER_IND_STATISTICS.

Что такое статистика таблиц и индексов и как она влияет на план запроса

Коллеги, всем привет!

С вами Кирилл Михалько.

Сегодня поговорим о статистике. Оптимизатор Oracle выбирает план выполнения запроса не наугад - он опирается на статистику. Без актуальной статистики даже идеально написанный SQL может работать в сотни раз медленнее. Сегодня разберём, что это за статистика, где она хранится и почему её нужно регулярно обновлять.

Что такое статистика

Статистика - это метаданные о таблицах и индексах, которые Oracle собирает и хранит в системных представлениях.

Основные метрики:

🔹 NUM_ROWS - количество строк в таблице

🔹 NUM_DISTINCT - количество уникальных значений в столбце

🔹 DENSITY - плотность распределения данных

🔹 LOW_VALUE / HIGH_VALUE - минимальное и максимальное значения

🔹 HISTOGRAM - распределение данных для столбцов с неравномерными значениями

🔹 CLUSTERING_FACTOR - степень упорядоченности данных относительно индекса

Эти данные хранятся в представлениях USER_TABLES, USER_TAB_COLUMNS, USER_TAB_STATISTICS, USER_INDEXES, USER_IND_STATISTICS.

Как статистика влияет на план запроса

Оптимизатор использует статистику для оценки кардинальности (cardinality) - предполагаемого количества строк на каждом шаге выполнения. От точности этой оценки зависит выбор метода доступа и порядка соединения таблиц.

Пример проблемы с устаревшей статистикой:

-- Таблица ORDERS содержит 10 млн строк, но статистика показывает 100 тыс.

SELECT o.order_id, c.customer_name

FROM orders o

JOIN customers c ON o.customer_id = c.customer_id

WHERE o.order_date > SYSDATE - 7;

Если статистика устарела, оптимизатор может:

✅ Выбрать NESTED LOOPS вместо HASH JOIN (думая, что строк мало)

✅ Использовать индекс там, где эффективнее FULL TABLE SCAN

✅ Неправильно оценить размер временных таблиц в памяти

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

Когда и как собирать статистику

Oracle предоставляет пакет DBMS_STATS для управления статистикой:

-- Сбор статистики для таблицы

BEGIN

DBMS_STATS.GATHER_TABLE_STATS(

ownname => 'SCHEMA_NAME',

tabname => 'ORDERS',

estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,

method_opt => 'FOR ALL COLUMNS SIZE AUTO',

degree => 4

);

END;

/

Ключевые параметры:

🔹 estimate_percent - процент выборки (AUTO_SAMPLE_SIZE обычно оптимален)

🔹 method_opt - определяет сбор гистограмм (SIZE AUTO позволяет Oracle решать автоматически)

🔹 degree - степень параллелизма

⚠️ Важные моменты:

🔹Собирайте статистику после массовых загрузок данных (INSERT, UPDATE, DELETE > 10% строк)

🔹Используйте автоматическую задачу сбора статистики

🔹Для партиционированных таблиц собирайте статистику на уровне партиций и глобально

🔹Проверяйте актуальность статистики через STALE_STATS в USER_TAB_STATISTICS

Диагностика проблем со статистикой

Признаки устаревшей или некорректной статистики:

❌ Большая разница между A-Rows и E-Rows в плане выполнения (EXECUTION PLAN)

❌ Внезапное изменение плана запроса без изменений в SQL

❌ Оптимизатор выбирает явно неоптимальный метод доступа

Проверка актуальности:

select t.table_name, t.stale_stats

from user_tab_statistics t

where t.table_name='ORDERS';

Если STALE_STATS = "YES" - пора обновить статистику.

Подытожим

Главное - помнить три вещи:

🔸 статистика - это основа для принятия решений оптимизатором

🔸 устаревшая статистика приводит к неоптимальным планам выполнения

🔸 регулярный сбор статистики - обязательная часть обслуживания БД.

Проверяйте актуальность статистики при проблемах с производительностью - часто это первопричина медленных запросов.

А как вы управляете статистикой в своих проектах? Используете автоматический сбор или настраиваете вручную? Поделитесь опытом в комментариях 💬

Успехов в оптимизации и быстрых запросов! 🚀

#oracle #статистика #оптимизация_запросов #sql #производительность #dbms_stats #database #Kirill_Mihalko

Канал Oracle Developer | Чатик 💬

Мини-курс Оптимизация: Быстрый старт 🚀

📱 Facebook 📱 YouTube 📱 ВКонтакте 📱 LinkedIn 📱 Threads RUTUBE