dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
PRODUCTION DIAGNOSTICS & OPERATIONAL SCRIPTS LIBRARY

100 Production DBA & SRE Diagnostic Scripts

Read-only diagnostic queries for PostgreSQL, MySQL, SQL Server, Oracle, and MongoDB covering lock chains, bloat, replication lag, cache hits, and bottleneck identification.

100 Verified Scripts
Read-Only Diagnostics
5 Database Engines
Showing scripts: 100 / 100ALL · ALL
#1
postgresql
Performance
read-onlyMin: 9.6

Find Long-Running Queries and Idle-in-Transaction Sessions in PostgreSQL

Lists queries running longer than a minute, their wait events, and idle-in-transaction sessions that block vacuum. The first script to run during a performance incident.

#pg_stat_activity#long-running#sessions#incident
sql
SELECT pid, usename, datname, state,
       now() - query_start AS query_age,
       now() - xact_start  AS xact_age,
       wait_event_type, wait_event,
       left(query, 200) AS query
FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
  AND state <> 'idle'
  AND now() - query_start > interval '1 minute'
ORDER BY query_start;

Note: `idle in transaction` sessions block vacuum. To terminate them (write action), run `SELECT pg_cancel_backend(pid);`, or `pg_terminate_backend(pid)` if it does not respond.

Details & Share
#2
postgresql
Locking
read-onlyMin: 9.6

PostgreSQL Lock Chain: Who Is Blocking Whom?

Uses pg_blocking_pids to pair blocked and blocking sessions with their queries and wait times. Shows the root cause of a lock chain in seconds.

#locks#blocking#pg_blocking_pids#deadlock
sql
SELECT blocked.pid                AS blocked_pid,
       blocked.usename            AS blocked_user,
       left(blocked.query, 120)   AS blocked_query,
       blocker.pid                AS blocking_pid,
       blocker.usename            AS blocking_user,
       blocker.state              AS blocking_state,
       left(blocker.query, 120)   AS blocking_query,
       now() - blocked.query_start AS waiting_for
FROM pg_stat_activity blocked
JOIN LATERAL unnest(pg_blocking_pids(blocked.pid)) AS b(pid) ON true
JOIN pg_stat_activity blocker ON blocker.pid = b.pid
ORDER BY waiting_for DESC;

Note: The PID at the very top of the chain (not blocked by any other session) is the root cause blocker.

Details & Share
#3
postgresql
Maintenance
read-onlyMin: 9.4

PostgreSQL Dead Tuples, Bloat and Autovacuum Health Check

Shows dead tuple ratio and last vacuum/analyze times per table. Helps you find tables where autovacuum settings are not keeping up.

#vacuum#autovacuum#bloat#dead-tuples
sql
SELECT schemaname, relname,
       n_live_tup, n_dead_tup,
       round(100.0 * n_dead_tup / NULLIF(n_live_tup + n_dead_tup, 0), 2) AS dead_pct,
       last_vacuum, last_autovacuum, last_autoanalyze,
       pg_size_pretty(pg_total_relation_size(relid)) AS total_size
FROM pg_stat_user_tables
WHERE n_dead_tup > 10000
ORDER BY n_dead_tup DESC
LIMIT 30;

Note: If `dead_pct` is consistently above 20%, consider lowering `autovacuum_vacuum_scale_factor` for that specific table.

Details & Share
#4
postgresql
Performance
read-onlyMin: 9.2

Find Unused Indexes in PostgreSQL

Lists never-scanned indexes that are neither unique nor primary keys, with their sizes. Surfaces cleanup candidates to cut write overhead and disk usage.

#index#unused-index#pg_stat_user_indexes#cleanup
sql
SELECT s.schemaname, s.relname AS table_name, s.indexrelname AS index_name,
       s.idx_scan,
       pg_size_pretty(pg_relation_size(s.indexrelid)) AS index_size
FROM pg_stat_user_indexes s
JOIN pg_index i ON i.indexrelid = s.indexrelid
WHERE s.idx_scan = 0
  AND NOT i.indisunique
  AND NOT i.indisprimary
ORDER BY pg_relation_size(s.indexrelid) DESC
LIMIT 30;

Note: Statistics reflect usage since the last reset (`pg_stat_database.stats_reset`). Also check indexes used on replicas. Always drop with `DROP INDEX CONCURRENTLY`.

Details & Share
#5
postgresql
Performance
read-onlyMin: 13 (eski sürümde `total_time`, `mean_time`)

Top 20 Most Expensive PostgreSQL Queries with pg_stat_statements

Ranks queries by total time, call count and mean time. Tells you which query to tune first.

#pg_stat_statements#top-queries#tuning
sql
-- Gerekli: CREATE EXTENSION pg_stat_statements; (shared_preload_libraries)
SELECT round(total_exec_time::numeric, 0) AS total_ms,
       calls,
       round(mean_exec_time::numeric, 2)  AS mean_ms,
       round((100 * total_exec_time / sum(total_exec_time) OVER ())::numeric, 2) AS pct_total,
       rows,
       left(query, 150) AS query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#6
postgresql
Replication
read-onlyMin: 10

Measure PostgreSQL Streaming Replication Lag

Shows WAL lag in bytes and time on the primary, and replay delay on the standby. Used to monitor replication health and RPO risk.

#replication#lag#streaming#wal
sql
-- 1. Primary Üzerinde (Run on Primary)
SELECT application_name, client_addr, state, sync_state,
       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)) AS replay_lag_bytes,
       write_lag, flush_lag, replay_lag
FROM pg_stat_replication;

-- 2. Standby Üzerinde (Run on Standby)
SELECT now() - pg_last_xact_replay_timestamp() AS replay_delay;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#7
postgresql
Monitoring
read-onlyMin: 9.x

PostgreSQL Transaction ID Wraparound Risk Check

Shows XID age per database and how close it is to the wraparound limit. A reliable alert source to catch a critical outage early.

#xid#wraparound#freeze#critical
sql
SELECT datname,
       age(datfrozenxid) AS xid_age,
       round(100.0 * age(datfrozenxid) / 2147483647, 2) AS pct_to_wraparound
FROM pg_database
ORDER BY xid_age DESC;

Note: Aggressive vacuum triggers as transaction age approaches `autovacuum_freeze_max_age` (default 200M). Alert when utilization exceeds 50%.

Details & Share
#8
postgresql
Storage
read-onlyMin: 9.x

Largest Tables and Index Sizes in PostgreSQL

Ranks tables by table, index and total size with estimated row counts. Used for capacity planning and spotting partitioning candidates.

#table-size#capacity#pg_class#index-size
sql
SELECT n.nspname AS schema_name, c.relname AS table_name,
       pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size,
       pg_size_pretty(pg_relation_size(c.oid))       AS table_size,
       pg_size_pretty(pg_indexes_size(c.oid))        AS index_size,
       c.reltuples::bigint AS est_rows
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r','m','p')
  AND n.nspname NOT IN ('pg_catalog','information_schema','pg_toast')
ORDER BY pg_total_relation_size(c.oid) DESC
LIMIT 25;

Note: `reltuples` is an estimate updated after `ANALYZE`.

Details & Share
#9
postgresql
Monitoring
read-onlyMin: 9.x

PostgreSQL Buffer Cache Hit Ratio

Computes the shared buffer hit ratio per database. Shows whether memory is undersized and whether too much data is read from disk.

#cache-hit#shared_buffers#pg_stat_database
sql
SELECT datname, blks_hit, blks_read,
       round(100.0 * blks_hit / NULLIF(blks_hit + blks_read, 0), 2) AS hit_pct
FROM pg_stat_database
WHERE datname IS NOT NULL
ORDER BY blks_read DESC;

Note: Expected to be above 99% in OLTP systems. Since the OS page cache also operates beneath PostgreSQL, interpret alongside `pg_stat_io` (PG 16+).

Details & Share
#10
postgresql
Performance
read-onlyMin: 9.x

PostgreSQL Tables with Heavy Sequential Scans

Finds tables that read many rows through sequential scans. A first step in identifying missing-index candidates.

#seq-scan#missing-index#pg_stat_user_tables
sql
SELECT schemaname, relname, seq_scan, seq_tup_read,
       idx_scan, n_live_tup,
       round(seq_tup_read::numeric / NULLIF(seq_scan, 0)) AS avg_rows_per_seq_scan
FROM pg_stat_user_tables
WHERE seq_scan > 0 AND n_live_tup > 10000
ORDER BY seq_tup_read DESC
LIMIT 20;

Note: Sequential scans on small tables are normal. Before adding an index, verify query execution plans using `EXPLAIN (ANALYZE, BUFFERS)`.

Details & Share
#11
postgresql
Performance
read-onlyMin: 9.x

Find Duplicate Indexes in PostgreSQL

Lists indexes defined identically on the same table, columns and predicate. Reduces unnecessary write cost and disk usage.

#duplicate-index#pg_index#cleanup
sql
SELECT indrelid::regclass AS table_name,
       array_agg(indexrelid::regclass) AS duplicate_indexes,
       pg_size_pretty(sum(pg_relation_size(indexrelid))) AS total_size
FROM pg_index
GROUP BY indrelid, indkey, indclass, indoption, indexprs::text, indpred::text
HAVING count(*) > 1;

Note: Remove redundant duplicates using `DROP INDEX CONCURRENTLY`; be cautious with indexes backing foreign key or uniqueness constraints.

Details & Share
#12
postgresql
Monitoring
read-onlyMin: 10

PostgreSQL Connection Usage vs max_connections

Groups connections by state and shows how close you are to max_connections. Helps decide whether you need a connection pooler.

#connections#max_connections#pg_stat_activity
sql
SELECT state, count(*) AS sessions,
       max(now() - state_change) AS longest_in_state
FROM pg_stat_activity
WHERE backend_type = 'client backend'
GROUP BY state
ORDER BY sessions DESC;

SELECT count(*) AS used,
       current_setting('max_connections')::int AS max_connections,
       round(100.0 * count(*) / current_setting('max_connections')::int, 1) AS used_pct
FROM pg_stat_activity;

Note: If usage exceeds 80%, evaluate deploying a connection pooler such as PgBouncer.

Details & Share
#13
postgresql
Replication
read-onlyMin: 10

PostgreSQL Replication Slots and Retained WAL

Shows inactive slots and the WAL they retain. Critical for preventing an abandoned slot from filling the disk.

#replication-slot#wal#disk-full
sql
SELECT slot_name, slot_type, active, restart_lsn,
       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal
FROM pg_replication_slots
ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC NULLS LAST;

Note: Inactive replication slots retain WAL files on disk indefinitely, risking complete filesystem saturation.

Details & Share
#14
postgresql
Storage
read-onlyMin: 9.x

PostgreSQL Database Sizes and Temp File Usage

Shows each database's size with rollback, deadlock and temp file stats. Used for growth tracking and a quick health summary.

#database-size#capacity#pg_database
sql
SELECT d.datname,
       pg_size_pretty(pg_database_size(d.datname)) AS size,
       s.xact_commit, s.xact_rollback, s.deadlocks,
       s.temp_files, pg_size_pretty(s.temp_bytes) AS temp_size
FROM pg_database d
JOIN pg_stat_database s ON s.datname = d.datname
WHERE NOT d.datistemplate
ORDER BY pg_database_size(d.datname) DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#15
postgresql
Monitoring
read-onlyMin: 9.x

PostgreSQL Checkpoint and Background Writer Stats

Shows scheduled versus requested checkpoint counts. Used to judge whether max_wal_size is adequate.

#checkpoint#bgwriter#io
sql
-- PostgreSQL 16 ve öncesi
SELECT checkpoints_timed, checkpoints_req,
       round(100.0 * checkpoints_req / NULLIF(checkpoints_timed + checkpoints_req, 0), 1) AS req_pct,
       buffers_checkpoint, buffers_clean, buffers_backend, stats_reset
FROM pg_stat_bgwriter;

-- PostgreSQL 17+
SELECT num_timed, num_requested, write_time, sync_time, buffers_written, stats_reset
FROM pg_stat_checkpointer;

Note: If requested checkpoints exceed scheduled checkpoints, increase `max_wal_size` and adjust `checkpoint_completion_target`.

Details & Share
#16
postgresql
Performance
read-onlyMin: 13

PostgreSQL Queries Spilling to Temp Files

Finds queries that spill to disk because work_mem is too small. Gives a clear candidate list for memory tuning and query optimization.

#temp-files#work_mem#pg_stat_statements
sql
SELECT calls,
       pg_size_pretty(temp_blks_written * 8192) AS temp_written,
       round(mean_exec_time::numeric, 2) AS mean_ms,
       left(query, 150) AS query
FROM pg_stat_statements
WHERE temp_blks_written > 0
ORDER BY temp_blks_written DESC
LIMIT 20;

Note: Queries spilling to disk indicate insufficient `work_mem`. Tune `work_mem` for the specific session or query.

Details & Share
#17
postgresql
Performance
read-onlyMin: 10

Find Foreign Keys Without Supporting Indexes in PostgreSQL

Lists foreign keys with no index on the referencing side. A common cause of slow deletes, updates and lock contention.

#foreign-key#missing-index#locking
sql
SELECT c.conrelid::regclass AS table_name,
       c.conname AS fk_name,
       pg_get_constraintdef(c.oid) AS definition
FROM pg_constraint c
WHERE c.contype = 'f'
  AND NOT EXISTS (
    SELECT 1 FROM pg_index i
    WHERE i.indrelid = c.conrelid
      AND (string_to_array(i.indkey::text, ' ')::int2[])[1:array_length(c.conkey, 1)] @> c.conkey
  )
ORDER BY 1, 2;

Note: Unindexed foreign keys cause full table scans on child tables during DELETE/UPDATE operations on parent tables.

Details & Share
#18
postgresql
Security
read-only (pg_hba için superuser)Min: 10

PostgreSQL Privileged Roles and Insecure pg_hba Rules

Lists superusers and high-privilege roles plus 'trust' or weak authentication rules. A quick start for security audits and hardening.

#roles#superuser#pg_hba#hardening
sql
SELECT rolname, rolsuper, rolcreaterole, rolcreatedb, rolreplication, rolbypassrls, rolcanlogin, rolvaliduntil
FROM pg_roles
WHERE rolsuper OR rolcreaterole OR rolreplication OR rolbypassrls
ORDER BY rolsuper DESC, rolname;

SELECT line_number, type, database, user_name, address, auth_method
FROM pg_hba_file_rules
WHERE auth_method IN ('trust','password','md5')
ORDER BY line_number;

Note: Review `trust` or overly broad CIDR rules (`0.0.0.0/0`) in `pg_hba.conf` and restrict superuser privileges.

Details & Share
#19
postgresql
Maintenance
read-onlyMin: 9.6

Track Running VACUUM Progress in PostgreSQL

Shows which phase each running vacuum is in and how far it has progressed. Helps estimate when a long vacuum will finish.

#vacuum#progress#pg_stat_progress_vacuum
sql
SELECT p.pid, p.datname, p.relid::regclass AS table_name, p.phase,
       p.heap_blks_total, p.heap_blks_scanned,
       round(100.0 * p.heap_blks_scanned / NULLIF(p.heap_blks_total, 0), 1) AS pct_scanned,
       now() - a.xact_start AS running_for,
       left(a.query, 80) AS query
FROM pg_stat_progress_vacuum p
JOIN pg_stat_activity a USING (pid);

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#20
postgresql
Monitoring
read-onlyMin: 10

Check PostgreSQL Sequences for Overflow Risk

Shows how close each sequence is to its data type limit. A sequence that hits the integer limit causes a production outage.

#sequence#overflow#integer
sql
SELECT schemaname, sequencename, data_type, last_value, max_value,
       round(100.0 * last_value / max_value, 2) AS pct_used
FROM pg_sequences
WHERE last_value IS NOT NULL
ORDER BY pct_used DESC
LIMIT 20;

Note: Alert when a sequence reaches 80% of its maximum value. Migrate `integer` primary keys to `bigint` before wraparound occurs.

Details & Share
#21
mysql
Performance
read-onlyMin: 5.7

Find Long-Running Queries in MySQL

Lists active queries running longer than 60 seconds from the processlist. Fast diagnosis for slowdowns and lock pile-ups.

#processlist#long-running#incident
sql
SELECT id, user, host, db, command, time AS seconds, state,
       LEFT(info, 200) AS query
FROM information_schema.processlist
WHERE command <> 'Sleep'
  AND time > 60
ORDER BY time DESC;

Note: To terminate a runaway query (write action): `KILL QUERY <id>;` or terminate the connection with `KILL <id>;`.

Details & Share
#22
mysql
Locking
read-onlyMin: 5.7 (sys şeması)

Find MySQL InnoDB Lock Waits and the Blocking Query

Uses the sys schema to show waiting and blocking sessions with lock modes. Resolves who is holding up whom in a single query.

#innodb#locks#sys-schema#blocking
sql
SELECT wait_started, wait_age,
       locked_table, locked_index, locked_type,
       waiting_pid, waiting_query,
       blocking_pid, blocking_query, blocking_lock_mode
FROM sys.innodb_lock_waits
ORDER BY wait_age DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#23
mysql
Storage
read-onlyMin: 5.7

List the Largest Tables and Disk Usage in MySQL

Ranks tables by data, index and free space size. Core input for capacity planning and archiving decisions.

#table-size#capacity#information_schema
sql
SELECT table_schema, table_name, engine, table_rows,
       ROUND(data_length  / 1024 / 1024, 1) AS data_mb,
       ROUND(index_length / 1024 / 1024, 1) AS index_mb,
       ROUND((data_length + index_length) / 1024 / 1024, 1) AS total_mb,
       ROUND(data_free / 1024 / 1024, 1) AS free_mb
FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','sys','information_schema','performance_schema')
ORDER BY (data_length + index_length) DESC
LIMIT 25;

Note: `DATA_FREE` indicates reclaimable space after heavy DELETE operations; reclaim via `OPTIMIZE TABLE` during low-traffic maintenance windows.

Details & Share
#24
mysql
Performance
read-onlyMin: 5.7

Detect Unused Indexes in MySQL

Uses sys.schema_unused_indexes to list indexes that were never used. Helps safely drop indexes that slow down writes.

#index#unused-index#sys-schema
sql
SELECT object_schema, object_name, index_name
FROM sys.schema_unused_indexes
WHERE object_schema NOT IN ('mysql','sys','performance_schema')
ORDER BY object_schema, object_name;

Note: Statistics reset on server reboot. Ensure sufficient uptime before safely dropping indexes.

Details & Share
#25
mysql
Performance
read-onlyMin: 5.7

Slowest MySQL Query Digests with Performance Schema

Groups similar queries to show total time, average time and no-index executions. Finds the costliest query patterns without enabling the slow log.

#performance_schema#digest#top-queries
sql
SELECT schema_name,
       LEFT(digest_text, 150) AS query_pattern,
       count_star AS exec_count,
       ROUND(sum_timer_wait / 1e12, 2) AS total_sec,
       ROUND(avg_timer_wait / 1e9, 2)  AS avg_ms,
       sum_rows_examined, sum_rows_sent,
       sum_no_index_used AS no_index_count
FROM performance_schema.events_statements_summary_by_digest
WHERE schema_name IS NOT NULL
ORDER BY sum_timer_wait DESC
LIMIT 20;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#26
mysql
Replication
read-onlyMin: 8.0.22 (eski: `SHOW SLAVE STATUS`)

MySQL Replication Status and Lag Check

Checks IO/SQL thread state, Seconds_Behind_Source and the latest errors. Quickly verifies replica health.

#replication#lag#replica
sql
-- 1. Replikasyon Durumu (Classic Replica Status)
SHOW REPLICA STATUS\G
-- Alanlar: Replica_IO_Running, Replica_SQL_Running, Seconds_Behind_Source

-- 2. Performance Schema ile (MySQL 8.0+)
SELECT channel_name, service_state, last_error_message
FROM performance_schema.replication_connection_status;

SELECT channel_name, service_state, last_error_message
FROM performance_schema.replication_applier_status_by_worker;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#27
mysql
Monitoring
read-onlyMin: 5.7

MySQL InnoDB Buffer Pool Hit Ratio

Compares buffer pool read requests against disk reads to compute the hit ratio. Tells you whether memory sizing is sufficient.

#innodb#buffer-pool#cache-hit
sql
SELECT
  (SELECT variable_value FROM performance_schema.global_status WHERE variable_name='Innodb_buffer_pool_read_requests') AS read_requests,
  (SELECT variable_value FROM performance_schema.global_status WHERE variable_name='Innodb_buffer_pool_reads')         AS disk_reads,
  ROUND(100 * (1 -
    (SELECT variable_value FROM performance_schema.global_status WHERE variable_name='Innodb_buffer_pool_reads') /
    NULLIF((SELECT variable_value FROM performance_schema.global_status WHERE variable_name='Innodb_buffer_pool_read_requests'), 0)
  ), 3) AS hit_ratio_pct;

Note: Target is 99%+ in OLTP environments. Lower ratios indicate memory pressure or poorly indexed queries evicting hot pages.

Details & Share
#28
mysql
Monitoring
read-onlyMin: 5.7

MySQL Connection Usage vs max_connections

Shows current connections, the peak seen and the breakdown by user and host. Used to catch 'Too many connections' errors early.

#connections#max_connections#threads
sql
SELECT
  (SELECT variable_value FROM performance_schema.global_status    WHERE variable_name='Threads_connected')   AS connected,
  (SELECT variable_value FROM performance_schema.global_status    WHERE variable_name='Max_used_connections') AS max_used,
  (SELECT variable_value FROM performance_schema.global_variables WHERE variable_name='max_connections')     AS max_connections,
  (SELECT variable_value FROM performance_schema.global_status    WHERE variable_name='Aborted_connects')    AS aborted_connects;

SELECT user, SUBSTRING_INDEX(host, ':', 1) AS client_host, COUNT(*) AS sessions
FROM information_schema.processlist
GROUP BY user, SUBSTRING_INDEX(host, ':', 1)
ORDER BY sessions DESC
LIMIT 20;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#29
mysql
Data Quality
read-onlyMin: 5.7

Find Tables Without a Primary Key in MySQL

Lists tables that have no primary key. Such tables cause replication lag and break Group Replication/Galera.

#primary-key#replication#schema
sql
SELECT t.table_schema, t.table_name, t.engine, t.table_rows
FROM information_schema.tables t
LEFT JOIN information_schema.table_constraints c
       ON c.table_schema = t.table_schema AND c.table_name = t.table_name
      AND c.constraint_type = 'PRIMARY KEY'
WHERE t.table_type = 'BASE TABLE'
  AND t.table_schema NOT IN ('mysql','sys','information_schema','performance_schema')
  AND c.constraint_name IS NULL
ORDER BY t.table_rows DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#30
mysql
Performance
read-onlyMin: 5.7

Find Redundant Indexes in MySQL

Lists indexes already covered by another index, with a ready-to-use DROP statement. Reduces write load and disk usage.

#redundant-index#sys-schema#cleanup
sql
SELECT table_schema, table_name,
       redundant_index_name, redundant_index_columns,
       dominant_index_name,  dominant_index_columns,
       sql_drop_index
FROM sys.schema_redundant_indexes
WHERE table_schema NOT IN ('mysql','sys');

Note: Drop redundant prefixes using `ALTER TABLE ... DROP INDEX ...` to reduce write I/O and disk bloat.

Details & Share
#31
mysql
Performance
read-onlyMin: 5.7

MySQL Queries Doing Full Table Scans

Ranks queries that scan whole tables without an index by total latency. The fastest way to find missing indexes.

#full-table-scan#sys-schema#missing-index
sql
SELECT db, LEFT(query, 150) AS query, exec_count,
       sys.format_time(total_latency) AS total_latency,
       no_index_used_count, rows_examined_avg
FROM sys.x$statements_with_full_table_scans
ORDER BY total_latency DESC
LIMIT 20;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#32
mysql
Performance
read-onlyMin: 5.7

MySQL Queries Creating On-Disk Temporary Tables

Shows the on-disk temp table ratio and the queries causing it. Gives hints for tmp_table_size and query optimization.

#tmp-table#disk-temp#memory
sql
SELECT variable_name, variable_value
FROM performance_schema.global_status
WHERE variable_name IN ('Created_tmp_tables','Created_tmp_disk_tables','Created_tmp_files');

SELECT db, LEFT(query, 150) AS query, exec_count, tmp_tables, disk_tmp_tables
FROM sys.statements_with_temp_tables
WHERE disk_tmp_tables > 0
ORDER BY disk_tmp_tables DESC
LIMIT 20;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#33
mysql
Locking
read-onlyMin: 5.7

Long-Open InnoDB Transactions in MySQL

Lists open transactions by age, locked rows and last query. Finds those blocking purge and bloating the history list.

#innodb#transaction#history-list
sql
SELECT trx_id, trx_state, trx_started,
       TIMESTAMPDIFF(SECOND, trx_started, NOW()) AS age_sec,
       trx_rows_locked, trx_rows_modified,
       trx_mysql_thread_id AS thread_id,
       LEFT(trx_query, 200) AS query
FROM information_schema.innodb_trx
ORDER BY trx_started;

SELECT name, count FROM information_schema.innodb_metrics WHERE name = 'trx_rseg_history_len';

Note: Long-running open transactions retain undo logs, preventing purge threads from cleaning undo history.

Details & Share
#34
mysql
Storage
read-onlyMin: 5.7

MySQL Database (Schema) Sizes

Ranks each schema by total size and table count. Used for capacity tracking and growth analysis.

#database-size#capacity#information_schema
sql
SELECT table_schema,
       COUNT(*) AS tables,
       ROUND(SUM(data_length)  / 1024 / 1024 / 1024, 2) AS data_gb,
       ROUND(SUM(index_length) / 1024 / 1024 / 1024, 2) AS index_gb,
       ROUND(SUM(data_length + index_length) / 1024 / 1024 / 1024, 2) AS total_gb
FROM information_schema.tables
GROUP BY table_schema
ORDER BY SUM(data_length + index_length) DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#35
mysql
Security
read-only (mysql.user okuma yetkisi)Min: 5.7

Risky MySQL User Accounts and Excess Privileges

Finds accounts with no password, open host access, or dangerous privileges like SUPER and FILE. A baseline check for security audits.

#users#privileges#hardening
sql
SELECT user, host, plugin,
       (authentication_string = '') AS no_password,
       account_locked, password_expired
FROM mysql.user
WHERE authentication_string = '' OR host = '%'
ORDER BY user;

SELECT grantee, privilege_type, is_grantable
FROM information_schema.user_privileges
WHERE privilege_type IN ('SUPER','FILE','SHUTDOWN','PROCESS')
ORDER BY grantee;

Note: Eliminate wildcard host accounts (`%`) for administrative users and revoke unnecessary global privileges.

Details & Share
#36
mysql
Monitoring
read-onlyMin: 5.7

MySQL AUTO_INCREMENT Overflow Risk

Calculates how close auto-increment columns are to their data type limit. Provides early warning because writes stop once the limit is hit.

#auto-increment#overflow#capacity
sql
SELECT table_schema, table_name, column_name, column_type, auto_increment,
       max_val, ROUND(100 * auto_increment / max_val, 2) AS pct_used
FROM (
  SELECT t.table_schema, t.table_name, c.column_name, c.column_type, t.auto_increment,
    CASE
      WHEN c.column_type LIKE 'tinyint%unsigned'   THEN 255
      WHEN c.column_type LIKE 'tinyint%'           THEN 127
      WHEN c.column_type LIKE 'smallint%unsigned'  THEN 65535
      WHEN c.column_type LIKE 'smallint%'          THEN 32767
      WHEN c.column_type LIKE 'mediumint%unsigned' THEN 16777215
      WHEN c.column_type LIKE 'mediumint%'         THEN 8388607
      WHEN c.column_type LIKE 'int%unsigned'       THEN 4294967295
      WHEN c.column_type LIKE 'int%'               THEN 2147483647
      WHEN c.column_type LIKE 'bigint%unsigned'    THEN 18446744073709551615
      ELSE 9223372036854775807
    END AS max_val
  FROM information_schema.tables t
  JOIN information_schema.columns c
    ON c.table_schema = t.table_schema AND c.table_name = t.table_name AND c.extra LIKE '%auto_increment%'
  WHERE t.auto_increment IS NOT NULL
    AND t.table_schema NOT IN ('mysql','sys','information_schema','performance_schema')
) x
ORDER BY pct_used DESC
LIMIT 20;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#37
mysql
Maintenance
read-onlyMin: 5.7

MySQL InnoDB Table Fragmentation and Reclaimable Space

Lists tables with large free space (data_free). Identifies candidates for space reclamation with OPTIMIZE TABLE.

#fragmentation#data_free#optimize
sql
SELECT table_schema, table_name,
       ROUND(data_length / 1048576, 1) AS data_mb,
       ROUND(data_free   / 1048576, 1) AS free_mb,
       ROUND(100 * data_free / NULLIF(data_length + index_length + data_free, 0), 1) AS free_pct
FROM information_schema.tables
WHERE engine = 'InnoDB' AND data_free > 100 * 1048576
ORDER BY data_free DESC
LIMIT 25;

Note: Run `OPTIMIZE TABLE` or `ALTER TABLE ... ENGINE=InnoDB` during off-peak maintenance hours to rebuild fragmented tablespaces.

Details & Share
#38
mysql
Backup
read-onlyMin: 5.7

MySQL Binary Log Size and Retention

Shows binary log files, their total size and the retention setting. Important for disk-full prevention and the point-in-time recovery window.

#binlog#disk#retention
sql
SHOW BINARY LOGS;

SELECT @@log_bin AS log_bin,
       @@binlog_format AS format,
       @@binlog_expire_logs_seconds / 86400 AS retention_days;   -- 8.0+; 5.7 için @@expire_logs_days

Note: Purge obsolete binary logs safely with `PURGE BINARY LOGS BEFORE NOW() - INTERVAL 7 DAY;`.

Details & Share
#39
mysql
Performance
read-onlyMin: 5.7

MySQL I/O Load by File

Ranks the most read and written files in bytes. Shows which table or file causes disk bottlenecks.

#io#performance_schema#disk
sql
SELECT file, count_read, total_read, count_write, total_written, total
FROM sys.io_global_by_file_by_bytes
LIMIT 20;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#40
mysql
Monitoring
read-onlyMin: 5.7

MySQL Memory Usage by Component

Shows the biggest memory consumers and total allocated memory. Used when investigating OOM kills and suspected memory leaks.

#memory#performance_schema#sys-schema
sql
SELECT event_name, current_count, current_alloc, high_alloc
FROM sys.memory_global_by_current_bytes
LIMIT 15;

SELECT * FROM sys.memory_global_total;

Note: Innodb_buffer_pool_size typically accounts for 60-80% of total system memory on dedicated database hosts.

Details & Share
#41
sqlserver
Locking
read-onlyMin: 2012

SQL Server Running Requests and Blocking Chain

Shows active requests, wait types, blocking sessions and the running statement together. The first diagnostic query to run during a slowdown.

#dmv#blocking#sessions#incident
sql
SELECT r.session_id, r.blocking_session_id, r.status, r.command,
       r.wait_type, r.wait_time AS wait_ms,
       r.cpu_time, r.logical_reads,
       DB_NAME(r.database_id) AS db_name,
       s.login_name, s.host_name,
       SUBSTRING(t.text, (r.statement_start_offset/2)+1,
         ((CASE r.statement_end_offset WHEN -1 THEN DATALENGTH(t.text)
           ELSE r.statement_end_offset END - r.statement_start_offset)/2)+1) AS running_statement
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s ON s.session_id = r.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.session_id <> @@SPID
  AND s.is_user_process = 1
ORDER BY r.blocking_session_id DESC, r.wait_time DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#42
sqlserver
Performance
read-onlyMin: 2012

Top CPU-Consuming Queries in SQL Server

Lists the top 20 queries by total and average CPU time from the plan cache. Pinpoints the source of CPU pressure at query level.

#query-stats#cpu#top-queries
sql
SELECT TOP 20
       qs.total_worker_time / 1000 AS total_cpu_ms,
       qs.execution_count,
       qs.total_worker_time / qs.execution_count / 1000 AS avg_cpu_ms,
       qs.total_logical_reads / qs.execution_count AS avg_logical_reads,
       qs.last_execution_time,
       SUBSTRING(t.text, (qs.statement_start_offset/2)+1,
         ((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(t.text)
           ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)+1) AS statement_text,
       DB_NAME(t.dbid) AS db_name
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) t
ORDER BY qs.total_worker_time DESC;

Note: High CPU queries frequently suffer from missing indexes or excessive scalar function invocations in WHERE clauses.

Details & Share
#43
sqlserver
Performance
read-onlyMin: 2008

SQL Server Missing Index Recommendations (Missing Index DMVs)

Ranks the optimizer's missing index suggestions by estimated benefit. Merge them with existing indexes before applying.

#missing-index#dmv#tuning
sql
SELECT TOP 20
       ROUND(gs.avg_total_user_cost * gs.avg_user_impact * (gs.user_seeks + gs.user_scans), 0) AS improvement_score,
       DB_NAME(mid.database_id) AS db_name,
       mid.statement AS table_name,
       mid.equality_columns, mid.inequality_columns, mid.included_columns,
       gs.user_seeks, gs.user_scans, gs.avg_user_impact
FROM sys.dm_db_missing_index_group_stats gs
JOIN sys.dm_db_missing_index_groups mig ON mig.index_group_handle = gs.group_handle
JOIN sys.dm_db_missing_index_details mid ON mid.index_handle = mig.index_handle
ORDER BY improvement_score DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#44
sqlserver
Maintenance
read-only (LIMITED modu)Min: 2008

SQL Server Index Fragmentation with Rebuild/Reorganize Advice

Measures fragmentation on large indexes and recommends rebuild or reorganize. Lets you plan maintenance windows without wasted work.

#fragmentation#rebuild#reorganize#index
sql
-- Mevcut veritabanında çalıştırın
SELECT TOP 50
       OBJECT_SCHEMA_NAME(ips.object_id) AS schema_name,
       OBJECT_NAME(ips.object_id)        AS table_name,
       i.name AS index_name,
       ips.avg_fragmentation_in_percent,
       ips.page_count,
       CASE WHEN ips.avg_fragmentation_in_percent >= 30 THEN 'REBUILD'
            ELSE 'REORGANIZE' END AS suggestion
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') ips
JOIN sys.indexes i ON i.object_id = ips.object_id AND i.index_id = ips.index_id
WHERE ips.avg_fragmentation_in_percent > 10
  AND ips.page_count > 1000
  AND i.index_id > 0
ORDER BY ips.avg_fragmentation_in_percent DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#45
sqlserver
Storage
read-onlyMin: 2008

SQL Server Data and Log File Size, Free Space and Autogrowth

Shows file size, used and free space, and growth settings. Used for capacity planning and catching bad autogrowth configs.

#files#capacity#autogrowth
sql
SELECT DB_NAME() AS db_name,
       f.name AS logical_name, f.type_desc, f.physical_name,
       CAST(f.size / 128.0 AS DECIMAL(18,1)) AS size_mb,
       CAST(FILEPROPERTY(f.name, 'SpaceUsed') / 128.0 AS DECIMAL(18,1)) AS used_mb,
       CAST((f.size - FILEPROPERTY(f.name, 'SpaceUsed')) / 128.0 AS DECIMAL(18,1)) AS free_mb,
       CASE WHEN f.is_percent_growth = 1 THEN CAST(f.growth AS VARCHAR(10)) + '%'
            ELSE CAST(f.growth / 128 AS VARCHAR(10)) + ' MB' END AS growth_setting
FROM sys.database_files f;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#46
sqlserver
Backup
read-onlyMin: 2008

SQL Server Last Backup Status and RPO Check

Shows the latest full, differential and log backup per database. Quickly finds databases without recent backups or log backups.

#backup#msdb#rpo#compliance
sql
SELECT d.name AS database_name, d.recovery_model_desc,
       MAX(CASE WHEN b.type = 'D' THEN b.backup_finish_date END) AS last_full,
       MAX(CASE WHEN b.type = 'I' THEN b.backup_finish_date END) AS last_diff,
       MAX(CASE WHEN b.type = 'L' THEN b.backup_finish_date END) AS last_log,
       DATEDIFF(HOUR, MAX(CASE WHEN b.type = 'D' THEN b.backup_finish_date END), GETDATE()) AS hours_since_full
FROM sys.databases d
LEFT JOIN msdb.dbo.backupset b ON b.database_name = d.name
WHERE d.name <> 'tempdb'
GROUP BY d.name, d.recovery_model_desc
ORDER BY hours_since_full DESC;

Note: Set alerts if full backup exceeds 24 hours or transaction log backup exceeds 15-30 minutes, violating recovery point objectives (RPO).

Details & Share
#47
sqlserver
Monitoring
read-onlyMin: 2008

SQL Server Wait Stats: Bottleneck Analysis

Lists top waits with percentages. The starting point to tell CPU, disk, locking or parallelism bottlenecks apart.

#wait-stats#bottleneck#dmv
sql
SELECT TOP 15
       wait_type,
       waiting_tasks_count,
       CAST(wait_time_ms / 1000.0 AS DECIMAL(18,1)) AS wait_sec,
       CAST(100.0 * wait_time_ms / SUM(wait_time_ms) OVER () AS DECIMAL(5,2)) AS pct
FROM sys.dm_os_wait_stats
WHERE wait_type NOT IN (
  'SLEEP_TASK','SLEEP_SYSTEMTASK','LAZYWRITER_SLEEP','SQLTRACE_BUFFER_FLUSH',
  'BROKER_TASK_STOP','BROKER_TO_FLUSH','XE_TIMER_EVENT','XE_DISPATCHER_WAIT',
  'REQUEST_FOR_DEADLOCK_SEARCH','CHECKPOINT_QUEUE','DIRTY_PAGE_POLL',
  'HADR_FILESTREAM_IOMGR_IOCOMPLETION','LOGMGR_QUEUE','WAITFOR','FT_IFTS_SCHEDULER_IDLE_WAIT',
  'SP_SERVER_DIAGNOSTICS_SLEEP','QDS_PERSIST_TASK_MAIN_LOOP_SLEEP','QDS_ASYNC_QUEUE',
  'SQLTRACE_INCREMENTAL_FLUSH_SLEEP','BROKER_EVENTHANDLER','CLR_AUTO_EVENT','CLR_MANUAL_EVENT')
  AND wait_time_ms > 0
ORDER BY wait_time_ms DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#48
sqlserver
Locking
read-onlyMin: 2012

Read Recent SQL Server Deadlocks from system_health

Pulls deadlock graphs from the system_health Extended Events session. Lets you analyze past deadlocks without enabling trace flags.

#deadlock#extended-events#system_health
sql
SELECT TOP 20
       x.event_data.value('(event/@timestamp)[1]', 'datetime2') AS event_time,
       x.event_data.query('(event/data[@name="xml_report"]/value/deadlock)[1]') AS deadlock_graph
FROM (
  SELECT CAST(target_data AS XML) AS target_data
  FROM sys.dm_xe_session_targets st
  JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address
  WHERE s.name = 'system_health' AND st.target_name = 'ring_buffer'
) AS tgt
CROSS APPLY tgt.target_data.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]') AS q(n)
CROSS APPLY (SELECT CAST(q.n.query('.') AS XML)) AS x(event_data)
ORDER BY event_time DESC;

Note: Deadlocks captured in the ring buffer can be parsed into XML deadlocks graphs for detailed locking analysis.

Details & Share
#49
sqlserver
Locking
read-onlyMin: 2012

Find Long-Open Transactions in SQL Server

Lists long-open transactions with their owners. Detects those blocking log truncation and holding locks.

#transaction#dbcc-opentran#log-reuse
sql
SELECT s.session_id, s.login_name, s.host_name, s.status,
       DB_NAME(t.database_id) AS db_name,
       at.transaction_begin_time,
       DATEDIFF(MINUTE, at.transaction_begin_time, GETDATE()) AS open_minutes,
       st.text AS last_sql
FROM sys.dm_tran_session_transactions t
JOIN sys.dm_tran_active_transactions at ON at.transaction_id = t.transaction_id
JOIN sys.dm_exec_sessions s ON s.session_id = t.session_id
LEFT JOIN sys.dm_exec_connections c ON c.session_id = s.session_id
OUTER APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) st
WHERE t.session_id <> @@SPID
ORDER BY at.transaction_begin_time;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#50
sqlserver
Performance
read-onlyMin: 2012

Find Unused and Costly Indexes in SQL Server

Finds indexes that are updated but never read. Produces a drop-candidate list to reduce write cost.

#unused-index#index-usage#dmv
sql
SELECT OBJECT_SCHEMA_NAME(i.object_id) AS schema_name,
       OBJECT_NAME(i.object_id) AS table_name,
       i.name AS index_name, i.type_desc,
       ISNULL(s.user_seeks,0) + ISNULL(s.user_scans,0) + ISNULL(s.user_lookups,0) AS reads,
       ISNULL(s.user_updates,0) AS writes,
       (SELECT SUM(ps.used_page_count) * 8 / 1024 FROM sys.dm_db_partition_stats ps
         WHERE ps.object_id = i.object_id AND ps.index_id = i.index_id) AS size_mb
FROM sys.indexes i
LEFT JOIN sys.dm_db_index_usage_stats s
       ON s.object_id = i.object_id AND s.index_id = i.index_id AND s.database_id = DB_ID()
WHERE OBJECTPROPERTY(i.object_id, 'IsUserTable') = 1
  AND i.type_desc = 'NONCLUSTERED'
  AND i.is_primary_key = 0 AND i.is_unique_constraint = 0
  AND ISNULL(s.user_seeks,0) + ISNULL(s.user_scans,0) + ISNULL(s.user_lookups,0) = 0
ORDER BY writes DESC;

Note: Indexes with high `user_updates` and zero `user_seeks`/`user_scans` incur heavy write penalties without providing read benefit.

Details & Share
#51
sqlserver
Replication
read-onlyMin: 2012

SQL Server Always On Availability Group Health and Lag

Shows replica states, synchronization health, log send and redo queues. Used to monitor failover readiness and data loss risk.

#always-on#availability-group#hadr
sql
SELECT ag.name AS ag_name, ar.replica_server_name, ar.availability_mode_desc,
       drs.database_id, DB_NAME(drs.database_id) AS db_name,
       drs.synchronization_state_desc, drs.synchronization_health_desc,
       drs.log_send_queue_size AS log_send_kb, drs.redo_queue_size AS redo_kb,
       drs.last_commit_time
FROM sys.dm_hadr_database_replica_states drs
JOIN sys.availability_replicas ar ON ar.replica_id = drs.replica_id
JOIN sys.availability_groups ag ON ag.group_id = drs.group_id
ORDER BY ag.name, ar.replica_server_name, db_name;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#52
sqlserver
Monitoring
read-onlyMin: 2012

SQL Server TempDB Usage and Top Space Consumers

Shows sessions using TempDB and the usage type (user, internal, version store). Finds the source of TempDB-full problems.

#tempdb#contention#space
sql
SELECT TOP 20 s.session_id, s.login_name, s.host_name,
       (u.user_objects_alloc_page_count - u.user_objects_dealloc_page_count) * 8 / 1024 AS user_obj_mb,
       (u.internal_objects_alloc_page_count - u.internal_objects_dealloc_page_count) * 8 / 1024 AS internal_obj_mb
FROM sys.dm_db_session_space_usage u
JOIN sys.dm_exec_sessions s ON s.session_id = u.session_id
ORDER BY user_obj_mb + internal_obj_mb DESC;

SELECT SUM(user_object_reserved_page_count) * 8 / 1024 AS user_mb,
       SUM(internal_object_reserved_page_count) * 8 / 1024 AS internal_mb,
       SUM(version_store_reserved_page_count) * 8 / 1024 AS version_store_mb,
       SUM(unallocated_extent_page_count) * 8 / 1024 AS free_mb
FROM tempdb.sys.dm_db_file_space_usage;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#53
sqlserver
Monitoring
read-onlyMin: 2008

SQL Server Agent Job Last-Run Status

Lists failed jobs and their latest run results. Catches backup and maintenance jobs failing silently.

#sql-agent#jobs#msdb
sql
SELECT j.name AS job_name, j.enabled,
       CASE h.run_status WHEN 0 THEN 'Failed' WHEN 1 THEN 'Succeeded' WHEN 2 THEN 'Retry'
                         WHEN 3 THEN 'Canceled' ELSE 'Unknown' END AS last_status,
       msdb.dbo.agent_datetime(h.run_date, h.run_time) AS last_run,
       h.message
FROM msdb.dbo.sysjobs j
OUTER APPLY (SELECT TOP 1 * FROM msdb.dbo.sysjobhistory
             WHERE job_id = j.job_id AND step_id = 0 ORDER BY instance_id DESC) h
ORDER BY CASE WHEN h.run_status = 0 THEN 0 ELSE 1 END, last_run DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#54
sqlserver
Maintenance
read-onlyMin: 2012 SP1

Find Stale Statistics in SQL Server

Lists statistics on tables with many modifications since the last update. Reveals a common cause of bad execution plans.

#statistics#cardinality#stale-stats
sql
SELECT TOP 30 OBJECT_SCHEMA_NAME(s.object_id) AS schema_name,
       OBJECT_NAME(s.object_id) AS table_name, s.name AS stats_name,
       sp.last_updated, sp.rows, sp.modification_counter,
       CAST(100.0 * sp.modification_counter / NULLIF(sp.rows, 0) AS DECIMAL(10,1)) AS pct_modified
FROM sys.stats s
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) sp
WHERE OBJECTPROPERTY(s.object_id, 'IsUserTable') = 1
  AND sp.modification_counter > 1000
ORDER BY sp.modification_counter DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#55
sqlserver
Performance
read-onlyMin: 2008

SQL Server Disk I/O Latency by File

Calculates read/write latency in ms for every data and log file. Used to prove disk-related slowness.

#io-latency#virtual-file-stats#storage
sql
SELECT DB_NAME(vfs.database_id) AS db_name, mf.physical_name, mf.type_desc,
       vfs.num_of_reads, vfs.num_of_writes,
       CAST(vfs.io_stall_read_ms  / NULLIF(vfs.num_of_reads, 0)  AS DECIMAL(10,1)) AS avg_read_ms,
       CAST(vfs.io_stall_write_ms / NULLIF(vfs.num_of_writes, 0) AS DECIMAL(10,1)) AS avg_write_ms
FROM sys.dm_io_virtual_file_stats(NULL, NULL) vfs
JOIN sys.master_files mf ON mf.database_id = vfs.database_id AND mf.file_id = vfs.file_id
ORDER BY (vfs.io_stall_read_ms + vfs.io_stall_write_ms) DESC;

Note: Sustained read/write latencies exceeding 20ms typically indicate disk storage subsystem saturation.

Details & Share
#56
sqlserver
Monitoring
read-onlyMin: 2012

SQL Server Page Life Expectancy and Memory Status

Shows PLE, Memory Grants Pending and memory settings. Tells you quickly whether there is memory pressure.

#memory#page-life-expectancy#buffer-pool
sql
SELECT counter_name, cntr_value
FROM sys.dm_os_performance_counters
WHERE counter_name IN ('Page life expectancy','Memory Grants Pending','Total Server Memory (KB)','Target Server Memory (KB)')
  AND (object_name LIKE '%Buffer Manager%' OR object_name LIKE '%Memory Manager%');

SELECT physical_memory_kb / 1024 AS os_memory_mb,
       (SELECT CAST(value_in_use AS INT) FROM sys.configurations WHERE name = 'max server memory (MB)') AS max_server_memory_mb
FROM sys.dm_os_sys_info;

Note: PLE consistently below 300 seconds per 4GB of buffer pool indicates severe memory pressure and cache thrashing.

Details & Share
#57
sqlserver
Security
read-onlyMin: 2008

List Sysadmin and Risky Logins in SQL Server

Finds logins in the sysadmin role, SQL logins without password policy, and accounts with blank passwords. A baseline check for security audits.

#logins#sysadmin#hardening
sql
SELECT p.name AS login_name, p.type_desc, p.is_disabled,
       CASE WHEN r.member_principal_id IS NOT NULL THEN 1 ELSE 0 END AS is_sysadmin
FROM sys.server_principals p
LEFT JOIN sys.server_role_members r
       ON r.member_principal_id = p.principal_id
      AND r.role_principal_id = SUSER_ID('sysadmin')
WHERE p.type IN ('S','U','G') AND p.name NOT LIKE '##%'
ORDER BY is_sysadmin DESC, p.name;

SELECT name, is_policy_checked, is_expiration_checked
FROM sys.sql_logins
WHERE is_policy_checked = 0 OR PWDCOMPARE('', password_hash) = 1;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#58
sqlserver
Performance
read-onlyMin: 2008

SQL Server Plan Cache Bloat from Single-Use Ad-hoc Plans

Shows the number of single-use plans and the memory they take. Used to decide on 'optimize for ad hoc workloads'.

#plan-cache#ad-hoc#optimize-for-ad-hoc
sql
SELECT objtype,
       COUNT(*) AS plans,
       SUM(CASE WHEN usecounts = 1 THEN 1 ELSE 0 END) AS single_use_plans,
       CAST(SUM(CAST(size_in_bytes AS BIGINT)) / 1048576.0 AS DECIMAL(18,1)) AS total_mb,
       CAST(SUM(CASE WHEN usecounts = 1 THEN CAST(size_in_bytes AS BIGINT) ELSE 0 END) / 1048576.0 AS DECIMAL(18,1)) AS single_use_mb
FROM sys.dm_exec_cached_plans
GROUP BY objtype
ORDER BY total_mb DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#59
sqlserver
Storage
read-onlyMin: 2016 SP2

SQL Server Transaction Log Usage, VLF Count and Log Reuse Wait

Shows log fill level, the reason log reuse is waiting, and VLF count. The first place to look when a log file balloons.

#transaction-log#vlf#log-reuse
sql
SELECT d.name, d.recovery_model_desc, d.log_reuse_wait_desc,
       ls.total_log_size_in_bytes / 1048576 AS log_size_mb,
       CAST(ls.used_log_space_in_percent AS DECIMAL(5,1)) AS used_pct,
       (SELECT COUNT(*) FROM sys.dm_db_log_info(d.database_id)) AS vlf_count
FROM sys.databases d
CROSS APPLY sys.dm_db_log_space_usage ls   -- mevcut DB için; tümü için veritabanı bazında çalıştırın
WHERE d.database_id = DB_ID();

Note: A large number of small VLFs (Virtual Log Files) degrades transaction log write throughput and slows database recovery.

Details & Share
#60
sqlserver
Performance
read-onlyMin: 2016

Find Parameter Sniffing Candidates with Query Store

Finds queries with multiple plans and large duration variance. Diagnoses plan regressions and parameter sniffing problems.

#parameter-sniffing#query-store#plan-regression
sql
SELECT TOP 20 q.query_id,
       COUNT(DISTINCT p.plan_id) AS plan_count,
       MIN(rs.avg_duration) / 1000 AS min_avg_ms,
       MAX(rs.avg_duration) / 1000 AS max_avg_ms,
       MAX(rs.avg_duration) / NULLIF(MIN(rs.avg_duration), 0) AS ratio,
       LEFT(qt.query_sql_text, 150) AS query_text
FROM sys.query_store_query q
JOIN sys.query_store_query_text qt ON qt.query_text_id = q.query_text_id
JOIN sys.query_store_plan p ON p.query_id = q.query_id
JOIN sys.query_store_runtime_stats rs ON rs.plan_id = p.plan_id
GROUP BY q.query_id, qt.query_sql_text
HAVING COUNT(DISTINCT p.plan_id) > 1
ORDER BY ratio DESC;

Note: Query Store helps identify queries with high plan variance caused by parameter sniffing; consider `OPTIMIZE FOR` hints.

Details & Share
#61
oracle
Performance
read-only (DBA/SELECT_CATALOG_ROLE)Min: 11g

Oracle Active Sessions and Wait Events

Lists active user sessions with the running SQL_ID and wait event. Shows the live picture during performance issues.

#v$session#sessions#active#incident
sql
SELECT s.sid, s.serial#, s.username, s.status, s.machine, s.program,
       s.sql_id, s.event, s.wait_class, s.seconds_in_wait,
       ROUND(s.last_call_et / 60, 1) AS active_minutes
FROM   v$session s
WHERE  s.type = 'USER'
  AND  s.status = 'ACTIVE'
  AND  s.sid <> SYS_CONTEXT('USERENV','SID')
ORDER  BY s.last_call_et DESC;

Note: High `db file sequential read` indicates single-block index reads; `db file scattered read` indicates full table scans.

Details & Share
#62
oracle
Locking
read-onlyMin: 11g

Find Blocking Sessions in Oracle

Shows sessions that make others wait, with wait times. Identifies the root session to terminate in lock incidents.

#locks#blocking#enq-tx
sql
SELECT w.sid AS waiting_sid, w.username AS waiting_user,
       w.event, w.seconds_in_wait,
       b.sid AS blocking_sid, b.serial# AS blocking_serial,
       b.username AS blocking_user, b.status AS blocking_status,
       b.sql_id AS blocking_sql_id, b.prev_sql_id
FROM   v$session w
JOIN   v$session b ON b.sid = w.blocking_session
WHERE  w.blocking_session IS NOT NULL
ORDER  BY w.seconds_in_wait DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#63
oracle
Storage
read-onlyMin: 11g

Oracle Tablespace Usage Including Autoextend

Calculates tablespace usage against the real maximum, honoring autoextend limits. Catches space errors like ORA-01653 before they happen.

#tablespace#capacity#autoextend
sql
SELECT df.tablespace_name,
       ROUND(df.max_mb, 0)  AS max_mb,
       ROUND(df.alloc_mb, 0) AS allocated_mb,
       ROUND(df.alloc_mb - NVL(fs.free_mb, 0), 0) AS used_mb,
       ROUND(100 * (df.alloc_mb - NVL(fs.free_mb, 0)) / df.max_mb, 1) AS used_pct_of_max
FROM (SELECT tablespace_name,
             SUM(bytes) / 1048576 AS alloc_mb,
             SUM(CASE WHEN autoextensible = 'YES' THEN GREATEST(maxbytes, bytes) ELSE bytes END) / 1048576 AS max_mb
      FROM dba_data_files GROUP BY tablespace_name) df
LEFT JOIN (SELECT tablespace_name, SUM(bytes) / 1048576 AS free_mb
           FROM dba_free_space GROUP BY tablespace_name) fs
       ON fs.tablespace_name = df.tablespace_name
ORDER BY used_pct_of_max DESC;

Note: Tablespaces approaching 90% without autoextend enabled require immediate datafile addition or storage expansion.

Details & Share
#64
oracle
Performance
read-onlyMin: 10g

Top 20 Most Expensive Oracle SQL with v$sqlstats

Shows costliest SQL by elapsed time with executions, CPU and I/O. Tells you which SQL_ID to investigate for tuning.

#v$sqlstats#top-sql#elapsed-time
sql
SELECT * FROM (
  SELECT sql_id,
         executions,
         ROUND(elapsed_time / 1e6, 1) AS elapsed_sec,
         ROUND(elapsed_time / NULLIF(executions, 0) / 1e3, 2) AS avg_ms,
         ROUND(cpu_time / 1e6, 1) AS cpu_sec,
         buffer_gets, disk_reads, rows_processed
  FROM   v$sqlstats
  ORDER  BY elapsed_time DESC
) WHERE ROWNUM <= 20;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#65
oracle
Maintenance
read-onlyMin: 10g

Find Invalid Objects in Oracle

Lists INVALID objects in user schemas. Essential after upgrades and patching.

#invalid-objects#compile#post-upgrade
sql
SELECT owner, object_type, object_name, status, last_ddl_time
FROM   dba_objects
WHERE  status = 'INVALID'
  AND  owner NOT IN ('SYS','SYSTEM')
ORDER  BY owner, object_type, object_name;

Note: Recompile invalid objects with `ALTER [OBJECT_TYPE] [OBJECT_NAME] COMPILE;` or run `utlrp.sql`.

Details & Share
#66
oracle
Backup
read-onlyMin: 11g

Oracle FRA and Archive Log Usage Check

Shows Fast Recovery Area usage and reclaimable space. Must be monitored to prevent database hangs from a full FRA.

#fra#archivelog#recovery#rman
sql
SELECT name,
       ROUND(space_limit / 1073741824, 2)   AS limit_gb,
       ROUND(space_used / 1073741824, 2)    AS used_gb,
       ROUND(space_reclaimable / 1073741824, 2) AS reclaimable_gb,
       ROUND(100 * (space_used - space_reclaimable) / space_limit, 1) AS real_used_pct
FROM   v$recovery_file_dest;

SELECT file_type, percent_space_used, percent_space_reclaimable, number_of_files
FROM   v$recovery_area_usage
ORDER  BY percent_space_used DESC;

Note: FRA saturation halts database operations immediately as archive logs cannot be written.

Details & Share
#67
oracle
Monitoring
read-onlyMin: 10g

Track Long-Running Oracle Operations (v$session_longops)

Shows completion percentage and remaining time for RMAN, index builds and large scans. Helps estimate when a long job will finish.

#longops#progress#rman#index-build
sql
SELECT sid, serial#, username, opname, target,
       sofar, totalwork,
       ROUND(100 * sofar / NULLIF(totalwork, 0), 1) AS pct_done,
       ROUND(elapsed_seconds / 60, 1) AS elapsed_min,
       ROUND(time_remaining / 60, 1)  AS remaining_min,
       sql_id
FROM   v$session_longops
WHERE  totalwork > 0
  AND  sofar < totalwork
ORDER  BY time_remaining DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#68
oracle
Storage
read-onlyMin: 11g

Largest Segments and Tables in Oracle

Lists the tables, indexes and LOB segments that take the most space. Used for growth analysis and archiving decisions.

#segments#dba_segments#capacity
sql
SELECT * FROM (
  SELECT owner, segment_name, segment_type, tablespace_name,
         ROUND(bytes / 1048576, 1) AS size_mb
  FROM   dba_segments
  WHERE  owner NOT IN ('SYS','SYSTEM','SYSAUX','XDB','MDSYS','CTXSYS')
  ORDER  BY bytes DESC
) WHERE ROWNUM <= 25;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#69
oracle
Performance
read-onlyMin: 12c

Find Unused Indexes in Oracle (DBA_INDEX_USAGE)

Lists indexes not used by queries, with access counts. Produces drop candidates to reduce write cost.

#index-usage#v$object_usage#cleanup
sql
-- 12.2+ : DBA_INDEX_USAGE
SELECT i.owner, i.index_name, i.table_name, i.index_type,
       NVL(u.total_access_count, 0) AS total_access_count, u.last_used
FROM   dba_indexes i
LEFT JOIN dba_index_usage u ON u.owner = i.owner AND u.name = i.index_name
WHERE  i.owner NOT IN ('SYS','SYSTEM')
  AND  i.uniqueness = 'NONUNIQUE'
  AND  NVL(u.total_access_count, 0) = 0
ORDER  BY i.owner, i.table_name;

Note: Enable index monitoring with `ALTER INDEX ... MONITORING USAGE;` or inspect `DBA_INDEX_USAGE` in Oracle 12c+.

Details & Share
#70
oracle
Maintenance
read-onlyMin: 11g

Oracle Stale Optimizer Statistics

Finds tables with stale or missing statistics. Catches the most common cause of bad execution plans.

#statistics#stale-stats#optimizer
sql
SELECT owner, table_name, num_rows, last_analyzed, stale_stats
FROM   dba_tab_statistics
WHERE  owner NOT IN ('SYS','SYSTEM','XDB','MDSYS','CTXSYS')
  AND  object_type = 'TABLE'
  AND  (stale_stats = 'YES' OR last_analyzed IS NULL)
ORDER  BY num_rows DESC NULLS LAST;

Note: Tables with stale statistics produce sub-optimal execution plans; gather stats via `DBMS_STATS.GATHER_TABLE_STATS`.

Details & Share
#71
oracle
Replication
read-onlyMin: 11g

Oracle Data Guard Apply and Transport Lag

Shows transport and apply lag on the standby. Used to monitor DR readiness and potential data loss window.

#data-guard#standby#lag
sql
-- Standby üzerinde
SELECT name, value, unit, time_computed
FROM   v$dataguard_stats
WHERE  name IN ('transport lag','apply lag','apply finish time');

SELECT process, status, thread#, sequence#, block#
FROM   v$managed_standby
WHERE  process IN ('MRP0','RFS');

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#72
oracle
Monitoring
read-onlyMin: 11g

Oracle Hourly Redo Log Switch Count

Shows the log switch count per hour. Tells whether redo log sizing fits the workload and whether checkpoint pressure exists.

#redo#log-switch#v$log_history
sql
SELECT TO_CHAR(first_time, 'YYYY-MM-DD HH24') AS hour, COUNT(*) AS log_switches
FROM   v$log_history
WHERE  first_time > SYSDATE - 2
GROUP  BY TO_CHAR(first_time, 'YYYY-MM-DD HH24')
ORDER  BY 1 DESC;

SELECT group#, thread#, bytes / 1048576 AS size_mb, members, status FROM v$log;

Note: More than 4-6 log switches per hour during normal load suggests redo log files are undersized.

Details & Share
#73
oracle
Storage
read-onlyMin: 11g

Sessions Consuming Oracle TEMP Tablespace

Lists sessions and SQL consuming TEMP space. Finds the source of ORA-01652 errors.

#temp#sort#v$tempseg_usage
sql
SELECT s.sid, s.serial#, s.username, s.program, u.tablespace, u.segtype,
       ROUND(u.blocks * ts.block_size / 1048576, 1) AS temp_mb, u.sql_id
FROM   v$tempseg_usage u
JOIN   v$session s ON s.saddr = u.session_addr
JOIN   dba_tablespaces ts ON ts.tablespace_name = u.tablespace
ORDER  BY u.blocks DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#74
oracle
Monitoring
read-onlyMin: 11g

Oracle Undo Usage and ORA-01555 Risk

Shows undo block status and snapshot-too-old error counts. Evaluates whether undo_retention is adequate.

#undo#ora-01555#retention
sql
SELECT status, ROUND(SUM(bytes) / 1048576, 1) AS size_mb
FROM   dba_undo_extents
GROUP  BY status;

SELECT TO_CHAR(begin_time, 'YYYY-MM-DD HH24:MI') AS begin_time,
       undoblks, txncount, maxquerylen, ssolderrcnt, nospaceerrcnt
FROM   v$undostat
WHERE  begin_time > SYSDATE - 1
ORDER  BY begin_time DESC;

Note: ORA-01555 snapshot too old occurs when undo retention is shorter than the execution duration of long-running queries.

Details & Share
#75
oracle
Monitoring
read-onlyMin: 11g

Oracle SGA and PGA Memory Usage

Shows SGA components and PGA target versus actual usage. The first data point for memory sizing decisions.

#sga#pga#memory#advisor
sql
SELECT name, ROUND(bytes / 1048576) AS mb FROM v$sgainfo ORDER BY bytes DESC;

SELECT name, ROUND(value / 1048576) AS mb
FROM   v$pgastat
WHERE  name IN ('aggregate PGA target parameter','total PGA allocated','maximum PGA allocated','cache hit percentage');

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#76
oracle
Security
read-onlyMin: 11g

Oracle Privileged Users and Default Password Audit

Finds users with DBA privileges, accounts with default passwords and non-expiring passwords. A baseline check for hardening and audits.

#users#dba-role#default-password#hardening
sql
SELECT grantee, granted_role, admin_option
FROM   dba_role_privs
WHERE  granted_role IN ('DBA','SYSDBA','EXP_FULL_DATABASE','IMP_FULL_DATABASE')
ORDER  BY grantee;

SELECT d.username, u.account_status, u.profile
FROM   dba_users_with_defpwd d
JOIN   dba_users u ON u.username = d.username
ORDER  BY d.username;

SELECT username, account_status, expiry_date, profile FROM dba_users
WHERE  account_status = 'OPEN' AND expiry_date IS NULL;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#77
oracle
Performance
read-only (Diagnostics Pack lisansı)Min: 11g

Top Oracle Wait Events from ASH in the Last Hour

Extracts the busiest wait events and SQL from Active Session History over the last hour. Used for retrospective performance analysis.

#awr#wait-events#ash
sql
SELECT NVL(event, 'ON CPU') AS event, wait_class,
       COUNT(*) AS ash_samples,
       ROUND(100 * RATIO_TO_REPORT(COUNT(*)) OVER (), 1) AS pct
FROM   v$active_session_history
WHERE  sample_time > SYSDATE - 1/24
GROUP  BY event, wait_class
ORDER  BY ash_samples DESC
FETCH FIRST 15 ROWS ONLY;

Note: Active Session History (ASH) provides second-by-second visibility into session bottlenecks without trace overhead.

Details & Share
#78
oracle
Backup
read-onlyMin: 11g

Oracle RMAN Backup History and Failures

Lists recent RMAN backups with type, duration and status. Verifies that backups run and the RPO is met.

#rman#backup#rpo
sql
SELECT session_key, input_type, status,
       TO_CHAR(start_time, 'YYYY-MM-DD HH24:MI') AS start_time,
       TO_CHAR(end_time,   'YYYY-MM-DD HH24:MI') AS end_time,
       ROUND(elapsed_seconds / 60, 1) AS minutes,
       ROUND(output_bytes / 1073741824, 2) AS output_gb
FROM   v$rman_backup_job_details
WHERE  start_time > SYSDATE - 7
ORDER  BY start_time DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#79
oracle
Locking
read-onlyMin: 11g

Locked Objects and Lock Holders in Oracle

Shows which sessions hold locks on which objects. Gives object-level diagnosis for DDL and row lock issues.

#dba_waiters#enqueue#row-lock
sql
SELECT lo.session_id AS sid, s.serial#, s.username, s.status, s.machine,
       o.owner, o.object_name, o.object_type,
       DECODE(lo.locked_mode, 1,'NULL',2,'ROW SHARE',3,'ROW EXCL',4,'SHARE',5,'SHARE ROW EXCL',6,'EXCLUSIVE') AS lock_mode
FROM   v$locked_object lo
JOIN   dba_objects o ON o.object_id = lo.object_id
JOIN   v$session s   ON s.sid = lo.session_id
ORDER  BY o.owner, o.object_name;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#80
oracle
Monitoring
read-onlyMin: 11g

Oracle Process and Session Limit Usage

Shows current usage against the processes and sessions parameters. Catches ORA-00020 (maximum processes exceeded) in advance.

#processes#sessions#ora-00020
sql
SELECT resource_name, current_utilization, max_utilization, limit_value
FROM   v$resource_limit
WHERE  resource_name IN ('processes','sessions','transactions');

SELECT username, COUNT(*) AS sessions
FROM   v$session
WHERE  type = 'USER'
GROUP  BY username
ORDER  BY sessions DESC;

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#81
mongodb
Performance
read-onlyMin: 4.0

Find Long-Running Operations in MongoDB (currentOp)

Lists active operations running longer than 5 seconds with plan summary and lock-wait info. Helps pick the operation to kill during a slowdown.

#currentOp#long-running#incident
javascript
db.getSiblingDB("admin").aggregate([
  { $currentOp: { allUsers: true, idleConnections: false } },
  { $match: { active: true, secs_running: { $gt: 5 }, ns: { $not: /^(admin|local|config)\./ } } },
  { $project: { opid: 1, op: 1, ns: 1, secs_running: 1, client: 1, planSummary: 1,
                waitingForLock: 1, command: 1 } },
  { $sort: { secs_running: -1 } }
]);

Note: To terminate a long-running operation in MongoDB: `db.killOp(opid)`.

Details & Share
#82
mongodb
Storage
read-onlyMin: 4.0

MongoDB Collection and Index Sizes

Ranks collections by document count, data, storage and index size. Used for capacity planning and spotting bloated indexes.

#collstats#capacity#index-size
javascript
const mb = n => +(n / 1024 / 1024).toFixed(1);
const rows = db.getCollectionInfos({ type: "collection" }).map(c => {
  const s = db.getCollection(c.name).stats();
  return { collection: c.name, docs: s.count, data_mb: mb(s.size),
           storage_mb: mb(s.storageSize), index_mb: mb(s.totalIndexSize),
           avg_doc_bytes: s.avgObjSize };
}).sort((a, b) => (b.storage_mb + b.index_mb) - (a.storage_mb + a.index_mb));
console.table(rows);

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#83
mongodb
Performance
read-onlyMin: 3.2

Find Unused Indexes in MongoDB ($indexStats)

Lists never-used indexes per collection. Offers cleanup candidates to cut write cost and memory use.

#indexStats#unused-index#cleanup
javascript
const out = [];
db.getCollectionInfos({ type: "collection" }).forEach(c => {
  db.getCollection(c.name).aggregate([{ $indexStats: {} }]).forEach(i => {
    if (i.name !== "_id_" && i.accesses.ops === 0) {
      out.push({ collection: c.name, index: i.name, key: JSON.stringify(i.key), since: i.accesses.since });
    }
  });
});
console.table(out);

Note: Indexes with low or zero access counts consume memory in WiredTiger cache and slow down write operations.

Details & Share
#84
mongodb
Replication
read-onlyMin: 4.0

MongoDB Replica Set Lag and Oplog Window

Shows member state, lag behind the primary and the oplog window. Monitors replication health and resync risk.

#replica-set#lag#oplog
javascript
const st = rs.status();
const primary = st.members.find(m => m.stateStr === "PRIMARY");
st.members.map(m => ({
  member: m.name, state: m.stateStr, health: m.health,
  lag_sec: primary ? (primary.optimeDate - m.optimeDate) / 1000 : null,
  ping_ms: m.pingMs
}));
rs.printSecondaryReplicationInfo();   // 4.4 öncesi: rs.printSlaveReplicationInfo()
rs.printReplicationInfo();            // oplog penceresi

Note: Replica lag exceeding secondary oplog window risks falling off the oplog, requiring full initial sync.

Details & Share
#85
mongodb
Performance
Profiler'ı açmak hafif yazma etkisi yaratır; okuma salt okunurMin: 4.0

Analyze Slow MongoDB Queries with the Profiler

Groups system.profile data to reveal the slowest query patterns and COLLSCANs. Ideal for finding missing indexes.

#profiler#slow-query#system.profile
javascript
// Profiler'ı aç (100 ms üzeri): db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.aggregate([
  { $match: { op: { $in: ["query", "command", "update", "remove"] }, ns: { $not: /system\.profile/ } } },
  { $group: { _id: { ns: "$ns", planSummary: "$planSummary" },
              count: { $sum: 1 }, avg_ms: { $avg: "$millis" }, max_ms: { $max: "$millis" },
              avg_docs_examined: { $avg: "$docsExamined" }, avg_returned: { $avg: "$nreturned" } } },
  { $sort: { avg_ms: -1 } },
  { $limit: 20 }
]);

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#86
mongodb
Data Quality
read-onlyMin: 3.6

Find Duplicate Documents in MongoDB

Lists repeated values of a field with the related _id values. Required data cleanup before creating a unique index.

#duplicates#unique-index#aggregation
javascript
// "users" koleksiyonunda email alanı tekrar edenleri bul
db.users.aggregate([
  { $group: { _id: "$email", count: { $sum: 1 }, ids: { $push: "$_id" } } },
  { $match: { _id: { $ne: null }, count: { $gt: 1 } } },
  { $sort: { count: -1 } },
  { $limit: 50 }
], { allowDiskUse: true });

Note: Duplicate documents can be cleaned up or prevented by creating a unique index on key fields.

Details & Share
#87
mongodb
Monitoring
read-onlyMin: 4.0

MongoDB Connections and WiredTiger Cache Status

Summarizes connection usage and cache fill via serverStatus. Tells you whether the working set fits in RAM.

#serverStatus#connections#wiredtiger#cache
javascript
const s = db.serverStatus();
const wt = s.wiredTiger.cache;
({
  connections_current: s.connections.current,
  connections_available: s.connections.available,
  cache_max_gb: +(wt["maximum bytes configured"] / 1073741824).toFixed(2),
  cache_used_gb: +(wt["bytes currently in the cache"] / 1073741824).toFixed(2),
  cache_dirty_gb: +(wt["tracked dirty bytes in the cache"] / 1073741824).toFixed(2),
  pages_read_into_cache: wt["pages read into cache"],
  uptime_hours: +(s.uptime / 3600).toFixed(1)
});

Note: WiredTiger cache dirty percentage above 20% triggers aggressive foreground application thread eviction.

Details & Share
#88
mongodb
Monitoring
read-onlyMin: 4.0

MongoDB Connections by Client and Application

Groups open connections by client address and application name. Used to find the service leaking connections.

#connections#clients#currentOp
javascript
db.getSiblingDB("admin").aggregate([
  { $currentOp: { allUsers: true, idleConnections: true } },
  { $group: { _id: { app: "$appName", client: { $arrayElemAt: [{ $split: ["$client", ":"] }, 0] } },
              connections: { $sum: 1 }, active: { $sum: { $cond: ["$active", 1, 0] } } } },
  { $sort: { connections: -1 } },
  { $limit: 20 }
]);

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#89
mongodb
Locking
read-onlyMin: 4.0

MongoDB Operations Waiting for Locks

Lists operations with waitingForLock set and the resource they wait on. Diagnoses slowdowns from write conflicts and lock pressure.

#locks#waitingForLock#currentOp
javascript
db.getSiblingDB("admin").aggregate([
  { $currentOp: { allUsers: true } },
  { $match: { waitingForLock: true } },
  { $project: { opid: 1, op: 1, ns: 1, secs_running: 1, lockStats: 1, command: 1, client: 1 } },
  { $sort: { secs_running: -1 } }
]);

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#90
mongodb
Storage
read-onlyMin: 4.4

MongoDB Sharded Collection Data Distribution and Balancer Status

Shows data and document distribution per shard and the balancer state. Finds unbalanced shards and hot shard issues.

#sharding#chunks#balancer
javascript
sh.status();                       // genel durum
sh.isBalancerRunning();
sh.getBalancerState();

// Belirli koleksiyon için shard dağılımı:
db.getSiblingDB("mydb").orders.getShardDistribution();

Note: Verify that the shard balancer is running and chunks are evenly distributed across all shards.

Details & Share
#91
mongodb
Storage
read-onlyMin: 4.0

MongoDB Database Sizes and Disk Usage

Lists data, storage and index size for each database. Used for capacity tracking and seeing compression effect.

#dbstats#capacity#disk
javascript
const gb = n => +(n / 1073741824).toFixed(2);
db.adminCommand({ listDatabases: 1 }).databases.map(d => {
  const s = db.getSiblingDB(d.name).stats();
  return { db: d.name, data_gb: gb(s.dataSize), storage_gb: gb(s.storageSize),
           index_gb: gb(s.indexSize), collections: s.collections, objects: s.objects };
}).sort((a, b) => b.storage_gb - a.storage_gb);

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#92
mongodb
Performance
read-onlyMin: 4.0

Find COLLSCAN Queries in MongoDB

Lists queries doing collection scans in the profiler, with the examined-to-returned document ratio. The fastest way to find missing indexes.

#collscan#explain#missing-index
javascript
db.system.profile.find(
  { planSummary: "COLLSCAN", ns: { $not: /system\.profile/ } },
  { ns: 1, op: 1, millis: 1, docsExamined: 1, nreturned: 1, command: 1, ts: 1 }
).sort({ millis: -1 }).limit(20);

Note: COLLSCAN operations scan every document in the collection; add supporting indexes to eliminate collection scans.

Details & Share
#93
mongodb
Replication
read-onlyMin: 4.0

MongoDB Oplog Size and Replication Window

Shows the oplog size and how many hours of operations it holds. Measures the risk of a secondary falling behind and needing a resync.

#oplog#replica-set#resync
javascript
const o = db.getSiblingDB("local").oplog.rs;
const first = o.find().sort({ $natural: 1 }).limit(1).next().ts;
const last  = o.find().sort({ $natural: -1 }).limit(1).next().ts;
const stats = db.getSiblingDB("local").oplog.rs.stats();
({
  size_mb: Math.round(stats.maxSize / 1048576),
  used_mb: Math.round(stats.size / 1048576),
  window_hours: +((last.getTime() - first.getTime()) / 3600).toFixed(1)
});

Note: Oplog window must exceed the duration required to restore and apply backups or survive secondary node outages.

Details & Share
#94
mongodb
Data Quality
read-onlyMin: 4.0

Find Oversized Documents in MongoDB

Ranks the largest documents in a collection in bytes. Catches documents approaching the 16 MB limit and schema anti-patterns.

#document-size#16mb-limit#schema
javascript
db.orders.aggregate([
  { $project: { size: { $bsonSize: "$$ROOT" } } },
  { $sort: { size: -1 } },
  { $limit: 10 }
], { allowDiskUse: true });

Note: MongoDB BSON document limit is 16MB. Large documents near this threshold must be refactored or stored in GridFS.

Details & Share
#95
mongodb
Maintenance
read-onlyMin: 4.0

List MongoDB TTL Indexes and Retention Periods

Shows TTL indexes and retention periods per collection. Used to audit data retention policies and unexpected deletions.

#ttl#expire#retention
javascript
const out = [];
db.getCollectionInfos({ type: "collection" }).forEach(c => {
  db.getCollection(c.name).getIndexes().forEach(i => {
    if (i.expireAfterSeconds !== undefined) {
      out.push({ collection: c.name, index: i.name, key: JSON.stringify(i.key),
                 expire_days: +(i.expireAfterSeconds / 86400).toFixed(2) });
    }
  });
});
console.table(out);

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#96
mongodb
Security
read-onlyMin: 4.0

MongoDB User and Role Privilege Audit

Lists users with their roles and highlights root and high-privilege roles. A baseline check for security audits and least privilege.

#users#roles#authentication#hardening
javascript
db.getSiblingDB("admin").system.users.find(
  {}, { user: 1, db: 1, roles: 1, "credentials.SCRAM-SHA-256": { $exists: true } }
).toArray().map(u => ({
  user: u.user, db: u.db,
  roles: u.roles.map(r => r.role + "@" + r.db).join(", "),
  privileged: u.roles.some(r => ["root","dbOwner","userAdminAnyDatabase","clusterAdmin"].includes(r.role))
}));

Note: Ensure roles adhere to the principle of least privilege and review accounts with root or dbOwner access.

Details & Share
#97
mongodb
Monitoring
read-onlyMin: 4.0

MongoDB Transaction Stats and Write Conflicts

Shows open and aborted transaction counts. Reveals long transaction and conflict problems.

#transactions#serverStatus#write-conflict
javascript
const s = db.serverStatus();
({
  transactions: s.transactions,
  global_lock: s.globalLock.currentQueue,
  wt_concurrent: s.wiredTiger.concurrentTransactions
});

Note: High write conflicts in WiredTiger indicate document contention from concurrent writes to the same document or index key.

Details & Share
#98
mongodb
Maintenance
read-onlyMin: 4.2

MongoDB Index Build Progress

Shows the percentage and duration of in-flight index builds. Helps estimate when an index build on a large collection will finish.

#index-build#progress#currentOp
javascript
db.getSiblingDB("admin").aggregate([
  { $currentOp: { allUsers: true } },
  { $match: { $or: [ { "command.createIndexes": { $exists: true } }, { msg: /Index Build/ } ] } },
  { $project: { opid: 1, ns: 1, secs_running: 1, msg: 1, progress: 1, "command.indexes": 1 } }
]);

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share
#99
mongodb
Performance
read-onlyMin: 4.0

Scatter-Gather Queries in a Sharded MongoDB Cluster

Measures queries fanning out to all shards via mongos. Used to evaluate shard key choice and query targeting.

#sharding#scatter-gather#mongos
javascript
db.serverStatus().metrics.queryExecutor;

// mongos üzerinde hedefleme oranı: scannedObjects / returned ne kadar yüksekse,
// sorgu o kadar çok shard'a dağılıyor demektir.
db.getSiblingDB("admin").runCommand({ serverStatus: 1 }).metrics.query;

Note: Queries without shard key predicates target all shards (scatter-gather), causing network overhead and latency spikes.

Details & Share
#100
mongodb
Monitoring
read-onlyMin: 4.4

MongoDB Chunk Migrations and Balancer Errors

Reads recent chunk move events and errors from the config database. Detects balancer problems and unnecessary migrations.

#balancer#chunk-migration#config
javascript
db.getSiblingDB("config").changelog.find(
  { what: /moveChunk/ },
  { time: 1, what: 1, ns: 1, details: 1 }
).sort({ time: -1 }).limit(20);

Note: Verify in a staging environment prior to running in production. This is a read-only diagnostic query; it does not acquire exclusive locks.

Details & Share