← Назад к вопросам

Какие команды обновляют статистику?

3.0 Senior🔥 11 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Команды обновления статистики в Python и СУБД

Статистика в контексте Python разработки может относиться к разным системам: СУБД, индексам, кэшам и мониторингу. Рассмотрим основные команды и подходы.

1. PostgreSQL: ANALYZE

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

import psycopg2

connection = psycopg2.connect('dbname=mydb user=postgres')
cursor = connection.cursor()

# Обновить статистику одной таблицы
cursor.execute('ANALYZE users;')

# Обновить статистику всех таблиц
cursor.execute('ANALYZE;')

# Обновить конкретного столбца
cursor.execute('ANALYZE users (id, email);')

connection.commit()
cursor.close()
connection.close()

Особенности:

  • Обновляет pg_statistics системный каталог
  • Не блокирует таблицы на запись
  • Может работать параллельно с приложением
  • VACUUM обычно запускает ANALYZE автоматически
  • Важна для правильного выбора планов запросов

Когда запускать:

  • После массовых загрузок данных
  • После удаления большого количества строк
  • При медленных запросах
  • Периодически в автоматических заданиях

2. PostgreSQL: VACUUM

Описание: Очистка "мертвых" кортежей и обновление статистики.

import psycopg2

connection = psycopg2.connect('dbname=mydb user=postgres')
cursor = connection.cursor()

# Базовый VACUUM
cursor.execute('VACUUM;')

# VACUUM с ANALYZE (очистка + статистика)
cursor.execute('VACUUM ANALYZE;')

# VACUUM FULL (более агрессивный, блокирует таблицу)
cursor.execute('VACUUM FULL users;')

# VACUUM с параллелизацией (PostgreSQL 13+)
cursor.execute('VACUUM (ANALYZE, PARALLEL 2) users;')

connection.commit()
cursor.close()
connection.close()

Параметры VACUUM:

  • VERBOSE - подробный вывод
  • ANALYZE - обновить статистику
  • FREEZE - заморозить кортежи
  • FULL - полная очистка (медленнее, но эффективнее)
  • PARALLEL - параллельная очистка

Особенности:

  • Освобождает пространство на диске
  • Помогает избежать переполнения XID
  • Может идти в фоне (autovacuum)
  • FULL блокирует таблицу, используй редко

3. PostgreSQL: REINDEX

Описание: Пересоздание индексов для оптимизации.

import psycopg2

connection = psycopg2.connect('dbname=mydb user=postgres')
cursor = connection.cursor()

# Переиндексировать конкретный индекс
cursor.execute('REINDEX INDEX users_email_idx;')

# Переиндексировать таблицу (все индексы)
cursor.execute('REINDEX TABLE users;')

# Переиндексировать всю БД
cursor.execute('REINDEX DATABASE mydb;')

# Параллельное переиндексирование (PostgreSQL 13+)
cursor.execute('REINDEX (PARALLEL 2) TABLE users;')

connection.commit()
cursor.close()
connection.close()

Особенности:

  • Индексы могут фрагментироваться со временем
  • REINDEX улучшает производительность запросов
  • REINDEX TABLE блокирует таблицу на запись
  • Используй CONCURRENTLY для блокировки только читаемую
# Неблокирующее переиндексирование
cursor.execute('REINDEX INDEX CONCURRENTLY users_email_idx;')

4. MySQL/MariaDB: OPTIMIZE TABLE

Описание: Оптимизирует таблицу и индексы.

import mysql.connector

connection = mysql.connector.connect(
    host='localhost',
    user='root',
    password='password',
    database='mydb'
)
cursor = connection.cursor()

# Оптимизировать одну таблицу
cursor.execute('OPTIMIZE TABLE users;')

# Оптимизировать несколько таблиц
cursor.execute('OPTIMIZE TABLE users, orders, products;')

# Получить результат
for result in cursor.results:
    print(result)

connection.commit()
cursor.close()
connection.close()

Особенности:

  • Эквивалент VACUUM + ANALYZE в PostgreSQL
  • Блокирует таблицу во время оптимизации
  • Перестраивает структуру таблицы
  • Более агрессивна чем в PostgreSQL

5. Redis: SLOWLOG / INFO

Описание: Просмотр статистики и медленных команд.

import redis

r = redis.Redis(host='localhost', port=6379, db=0)

# Получить информацию о Redis (включая статистику)
info = r.info()
print(info['stats'])  # Статистика команд
print(info['memory'])  # Использование памяти

# Получить медленные команды
slow_log = r.slowlog_get(10)  # Последние 10 медленных команд
for entry in slow_log:
    print(f"Command: {entry['command']}, Duration: {entry['duration']}us")

# Очистить slowlog
r.slowlog_reset()

Особенности:

  • SLOWLOG фиксирует команды медленнее определенного порога
  • INFO выводит подробную статистику
  • MONITOR показывает все команды в реальном времени
  • Полезно для отладки и мониторинга

6. SQLite: ANALYZE

Описание: Сбор статистики для оптимизатора SQLite.

import sqlite3

connection = sqlite3.connect('mydb.db')
cursor = connection.cursor()

# Обновить статистику
cursor.execute('ANALYZE;')

# Обновить статистику конкретной таблицы
cursor.execute('ANALYZE users;')

# Просмотреть статистику
cursor.execute('SELECT * FROM sqlite_stat1;')
for row in cursor.fetchall():
    print(row)

connection.commit()
cursor.close()
connection.close()

Особенности:

  • Сохраняет статистику в sqlite_stat1, sqlite_stat3, sqlite_stat4
  • Помогает запросам быть более эффективными
  • Относительно легко (не блокирует)

7. Prometheus / Grafana: Метрики обновления

Описание: Сбор и визуализация метрик приложения.

from prometheus_client import Counter, Histogram, Gauge, start_http_server
import time

# Определение метрик
request_count = Counter('requests_total', 'Total requests', ['method', 'endpoint'])
request_duration = Histogram('request_duration_seconds', 'Request duration')
active_connections = Gauge('active_connections', 'Active connections')

def process_request(method, endpoint):
    # Увеличение счетчика
    request_count.labels(method=method, endpoint=endpoint).inc()
    
    # Измерение времени
    start = time.time()
    # ... логика
    request_duration.observe(time.time() - start)
    
    # Обновление gauge
    active_connections.inc()
    # ... логика
    active_connections.dec()

# Запуск Prometheus endpoint
if __name__ == '__main__':
    start_http_server(8000)
    # Prometheus будет скрейпить metrics с 8000 портов

Особенности:

  • Counter - только увеличивается
  • Gauge - может увеличиваться и уменьшаться
  • Histogram - распределение значений
  • Summary - квантили

8. Elasticsearch: Index Refresh / Flush

Описание: Обновление индексов поиска.

from elasticsearch import Elasticsearch

es = Elasticsearch(['localhost:9200'])

# Refresh индекса (сделать документы видимыми для поиска)
es.indices.refresh(index='users')

# Flush индекса (синхронизировать с диском)
es.indices.flush(index='users')

# Оптимизировать индекс (объединение сегментов)
es.indices.forcemerge(index='users', max_num_segments=1)

# Обновить статистику индекса
stats = es.indices.stats(index='users')
print(stats['indices']['users']['primaries']['docs'])

Особенности:

  • Refresh - для видимости новых документов (по умолчанию каждую секунду)
  • Flush - для durability
  • Forcemerge - для оптимизации размера на диске
  • Используется в production для тюнинга

9. Python Counter.update()

Описание: Программное обновление счетчиков.

from collections import Counter

# Исходный счетчик
counter = Counter(a=3, b=1)

# Обновление
counter.update({'a': 2, 'c': 4})
print(counter)  # Counter({'a': 5, 'c': 4, 'b': 1})

# Обновление списком
counter.update('abracadabra')
print(counter.most_common(3))

# Вычитание
counter.subtract({'a': 1, 'b': 1})
print(counter)

# Удаление нулевых элементов
+counter  # Возвращает новый Counter без нулевых элементов

Сравнительная таблица

СУБДКомандаБлокируетВремяUse Case
PGANALYZEНетбыстрОбновить оптимизацию
PGVACUUMНетсреднОчистить мертвые кортежи
PGVACUUM FULLДадолгоОсвободить место
MySQLOPTIMIZE TABLEДадолгоОптимизировать таблицу
SQLiteANALYZEНетбыстрОбновить статистику
ElasticRefreshНетбыстрВидимость документов
ElasticForcemergeНетдолгоОптимизировать размер

Best Practices

  1. Запускай ANALYZE регулярно в PostgreSQL после больших изменений
  2. Используй VACUUM ANALYZE вместе для лучшего результата
  3. Избегай VACUUM FULL в production (используй VACUUM обычный)
  4. Мониторь meduslog_log и slow_query_log
  5. Используй Prometheus для сбора метрик приложения
  6. Периодически REINDEX в PostgreSQL
  7. Настрой autovacuum параметры под нагрузку
  8. Собирай статистику после импорта больших объемов данных
# Пример: Обновление статистики после импорта
import psycopg2
import time

def update_statistics_after_import(db_connection, table_name):
    cursor = db_connection.cursor()
    
    print(f'Updating statistics for {table_name}...')
    start = time.time()
    
    cursor.execute(f'ANALYZE {table_name};')
    db_connection.commit()
    
    elapsed = time.time() - start
    print(f'Statistics updated in {elapsed:.2f} seconds')
    
    cursor.close()

Вывод: Регулярное обновление статистики критично для оптимизации производительности СУБД и приложения в целом. Выбор команд зависит от используемой системы хранения данных.

Какие команды обновляют статистику? | PrepBro