Umbrales de un DBA: no se listan indices chicos como fragmentados, no se propone borrar un indice por una sola escritura y no se trata una espera de 0 ms como bloqueo. Este archivo no aplico ningun cambio.
| Severidad | Area | Hallazgo | Detalle |
|---|---|---|---|
| Critical | Configuracion | AUTO_CLOSE esta ON | Cierra la base al quedar sin sesiones y tira planes y cache. |
| Critical | Configuracion | AUTO_SHRINK esta ON | Encoge y vuelve a crecer el archivo. Fragmenta datos y log. |
| Critical | Configuracion | PAGE_VERIFY no es CHECKSUM | Valor: NONE. Paginas rotas pueden pasar sin detectarse. |
| Critical | Durabilidad | DELAYED_DURABILITY = FORCED | Un apagon puede perder transacciones ya confirmadas por la aplicacion. |
| Critical | Estadisticas | Estadisticas automaticas desactivadas | auto_create=True, auto_update=False. Encenderlas no refresca las que ya estan viejas. |
| High | Almacenamiento | Crecimiento riesgoso en DBA_BI | Crecimiento 1MB, tamano 512 MB. En data, el crecimiento en porcentaje o menor a 64 MB provoca autogrow seguidos. |
| High | Almacenamiento | Crecimiento riesgoso en DBA_BI_log | Crecimiento 1MB, tamano 343 MB. En el log, crecer de a pocos MB crea muchos VLF. |
| High | Backup | El ultimo full tiene mas de 7 dias | Ultimo full: 09/10/2026 17:31:01. |
| High | Backup | Recovery FULL sin backup de log reciente | En FULL, sin backup de log el archivo de log crece y el RPO es el ultimo full o diferencial. |
| High | Bloqueos | Hay bloqueo en vivo de 15 segundos o mas | 1 solicitud(es). Cabeza visible en blocking_session_id. No mate la sesion desde este informe. |
| High | Estadisticas | Estadistica vieja lab.CdbFrag.CX_CdbFrag_Sort | 80000 cambios sobre 120000 filas (66.7%). |
| High | Estadisticas | Estadistica vieja lab.CdbStale.IX_CdbStale_Code | 2000 cambios sobre 2000 filas (100.0%). |
| High | Indices | Posible indice faltante en [DBA_BI].[lab].[CdbSeek] | Impacto 99.6%, seeks=300. Igualdad: [CustomerId]. Desigualdad: [OrderDate]. |
| High | Mantenimiento | Indice fragmentado lab.CdbFrag.CX_CdbFrag_Sort | 99.1% en 26483 paginas. Accion sugerida: REBUILD. |
| High | Optimizador | Legacy cardinality estimator ON | Fuerza el estimador anterior a SQL 2014. Puede empeorar planes nuevos. |
| High | Paralelismo | Cost threshold for parallelism demasiado bajo | Valor actual 5. Consultas pequenas se van en paralelo. Un punto de partida habitual es 50, medido con el workload. |
| High | Seguridad | TRUSTWORTHY esta ON | Permite elevar privilegios desde modulos de esta base. Dejelo OFF salvo un requisito auditado. |
| Medium | Log | VLF elevados | 221 VLF. |
| Medium | Memoria | max server memory no deja margen al sistema operativo | max server memory=2147483647 MB y la RAM fisica es 3960 MB. |
| Medium | Paralelismo | MAXDOP de la base = 1 | El paralelismo esta apagado solo en esta base. Confirme que es intencional. |
| Medium | Query Store | Query Store captura ALL | En una base ocupada ALL llena el almacen con consultas de un solo uso. AUTO es mas seguro. |
| Low | Plan cache | optimize for ad hoc workloads esta apagado | Con mucho SQL ad hoc el cache guarda planes de un solo uso. La opcion guarda solo el stub en el primer uso. |
| name | value_in_use | description |
|---|---|---|
| backup checksum default | 0 | Enable checksum of backups by default |
| backup compression default | 0 | Enable compression of backups by default |
| cost threshold for parallelism | 5 | cost threshold for parallelism |
| fill factor (%) | 0 | Default fill factor percentage |
| max degree of parallelism | 2 | maximum degree of parallelism |
| max server memory (MB) | 2147483647 | Maximum size of server memory (MB) |
| max worker threads | 0 | Maximum worker threads |
| min server memory (MB) | 16 | Minimum size of server memory (MB) |
| optimize for ad hoc workloads | 0 | When this option is set, plan cache size is further reduced for single-use adhoc OLTP workload. |
| remote query timeout (s) | 600 | remote query timeout |
| name | state_desc | recovery_model_desc | compatibility_level | collation_name | page_verify_option_desc | is_auto_close_on | is_auto_shrink_on | is_auto_create_stats_on | is_auto_update_stats_on | is_auto_update_stats_async_on | is_trustworthy_on | is_read_committed_snapshot_on | is_parameterization_forced | log_reuse_wait_desc | delayed_durability_desc | user_access_desc |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| DBA_BI | ONLINE | FULL | 160 | SQL_Latin1_General_CP1_CI_AS | NONE | True | True | True | False | False | True | False | False | LOG_BACKUP | FORCED | MULTI_USER |
| name | value | value_for_secondary |
|---|---|---|
| ACCELERATED_PLAN_FORCING | True | |
| LEGACY_CARDINALITY_ESTIMATION | True | |
| MAXDOP | 1 | |
| PARAMETER_SNIFFING | True | |
| QUERY_OPTIMIZER_HOTFIXES | False |
| Espera | Tareas | Espera_recurso_ms | Espera_signal_ms | Pct_recurso |
|---|---|---|---|---|
| SOS_WORK_DISPATCHER | 638441 | 2660283202 | 186824 | 99,98 |
| WRITELOG | 66267 | 172674 | 3866 | 0,01 |
| PWAIT_ALL_COMPONENTS_INITIALIZED | 3 | 81938 | 10 | 0,00 |
| PAGEIOLATCH_SH | 1592 | 47043 | 969 | 0,00 |
| ASYNC_IO_COMPLETION | 7 | 35469 | 94 | 0,00 |
| BACKUPIO | 365 | 34716 | 8 | 0,00 |
| LCK_M_X | 166 | 33175 | 44 | 0,00 |
| IO_COMPLETION | 1382 | 28731 | 50 | 0,00 |
| BACKUPBUFFER | 403 | 28296 | 64 | 0,00 |
| PREEMPTIVE_OS_QUERYREGISTRY | 325931 | 26334 | 0 | 0,00 |
| LCK_M_S | 16 | 20191 | 2 | 0,00 |
| PREEMPTIVE_OS_WRITEFILE | 3154 | 12546 | 0 | 0,00 |
| PAGEIOLATCH_EX | 647 | 9353 | 53 | 0,00 |
| PREEMPTIVE_OS_FLUSHFILEBUFFERS | 243 | 8274 | 0 | 0,00 |
| CXCONSUMER | 125 | 6562 | 73 | 0,00 |
| PREEMPTIVE_OS_FILEOPS | 1144 | 5319 | 0 | 0,00 |
| PREEMPTIVE_OS_AUTHENTICATIONOPS | 38844 | 5251 | 0 | 0,00 |
| MSQL_XP | 4482 | 4776 | 0 | 0,00 |
| WRITE_COMPLETION | 105 | 3816 | 36 | 0,00 |
| THREADPOOL | 61 | 3243 | 0 | 0,00 |
Acumulado desde el arranque de SQL. No es una ventana de una hora como el AWR. CXCONSUMER, solo, no es un problema de paralelismo.
| actual_state_desc | desired_state_desc | readonly_reason | current_storage_size_mb | max_storage_size_mb | query_capture_mode_desc | stale_query_threshold_days | size_based_cleanup_mode_desc |
|---|---|---|---|---|---|---|---|
| READ_WRITE | READ_WRITE | 0 | 6 | 1000 | ALL | 30 | AUTO |
| query_id | ejecuciones | duracion_total_ms | cpu_total_ms | lecturas_logicas | sql_text |
|---|---|---|---|---|---|
| 1821 | 3,00 | 32.337,55 | 0,41 | 15,00 | (@1 tinyint)UPDATE [lab].[CdbSeek] set [Amount] = [Amount] WHERE [OrderId]=@1 |
| 1 | 8,00 | 4.803,95 | 9.540,63 | 224.544,00 | SELECT SUM(CHECKSUM(Payload)) AS payload_checksum FROM lab.CdbFrag WHERE Payload LIKE '%Q%' |
| 1816 | 300,00 | 2.099,26 | 1.149,95 | 347.700,00 | (@c int)SELECT SUM(Amount) AS total_amount FROM lab.CdbSeek WHERE CustomerId = @c AND OrderDate >= '2024-06-01' |
| 1845 | 300,00 | 1.701,25 | 1.141,80 | 347.700,00 | (@c int,@sink decimal(18,2))SELECT @sink = SUM(Amount) FROM lab.CdbSeek WHERE CustomerId = @c AND OrderDate >= '2024-06-01' |
| 2 | 280,00 | 1.042,30 | 986,95 | 324.520,00 | (@c int)SELECT SUM(Amount) AS total_amount FROM lab.CdbSeek WHERE CustomerId = @c AND OrderDate >= '2024-06-01' |
| 1840 | 1,00 | 683,18 | 10,37 | 224,00 | SELECT TOP 1 CONVERT(decimal(18,1), avg_fragmentation_in_percent) AS frag, page_count FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('lab.CdbFrag'), NULL, NULL, 'LIMITED') WHERE page_count >= 1000 |
| 1832 | 1,00 | 602,93 | 25,44 | 8.332,00 | SELECT TOP (25) OBJECT_SCHEMA_NAME(ips.object_id) AS esquema, OBJECT_NAME(ips.object_id) AS tabla, i.name AS indice, CONVERT(decimal(18,1), ips.avg_fragmentation_in_percent) AS frag_pct, ips.page_count AS |
| 1827 | 1,00 | 344,36 | 240,20 | 11.055,00 | SELECT TOP (15) q.query_id, CONVERT(decimal(18,2), SUM(rs.count_executions)) AS ejecuciones, CONVERT(decimal(18,2), SUM(rs.avg_duration * rs.count_executions) / 1000.0) AS duracion_total_ms, CONVERT(decimal(1 |
| 1805 | 1,00 | 284,41 | 284,39 | 27.166,00 | SELECT (SELECT COUNT(*) FROM lab.CdbFrag) AS frag_rows, (SELECT COUNT(*) FROM lab.CdbSeek) AS seek_rows, (SELECT COUNT(*) FROM sys.dm_db_log_info(DB_ID())) AS vlf_count, (SELECT TOP (1) CONVERT(decima |
| 1808 | 1,00 | 66,50 | 0,88 | 148,00 | SELECT s.name, sp.rows, sp.modification_counter FROM sys.stats s CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) sp WHERE s.object_id = OBJECT_ID('lab.CdbStale') |
| 1817 | 1,00 | 48,56 | 48,56 | 0,00 | SELECT TOP (5) mid.statement AS objeto, migs.user_seeks AS seeks, CONVERT(decimal(18,1), migs.avg_user_impact) AS impacto FROM sys.dm_db_missing_index_groups mig JOIN sys.dm_db_missing_index_group_stats migs ON migs.grou |
| 1804 | 1,00 | 33,88 | 33,88 | 12,00 | UPDATE msdb.dbo.backupset SET backup_start_date = DATEADD(day, -12, GETDATE()), backup_finish_date = DATEADD(day, -12, GETDATE()) WHERE database_name = N'DBA_BI' AND type = 'D' AND backup_set_id = ( S |
| 1831 | 1,00 | 29,59 | 27,98 | 179,00 | SELECT TOP (25) OBJECT_SCHEMA_NAME(i.object_id) AS esquema, OBJECT_NAME(i.object_id) AS tabla, i.name AS indice, ISNULL(s.user_updates, 0) AS escrituras FROM sys.indexes i LEFT JOIN sys.dm_db_index_usage_st |
| 1828 | 1,00 | 26,12 | 24,43 | 1.369,00 | SELECT TOP (15) qs.execution_count AS ejecuciones, CONVERT(decimal(18,2), qs.total_elapsed_time / 1000.0) AS total_ms, CONVERT(decimal(18,2), qs.total_worker_time / 1000.0) AS cpu_ms, qs.total_logical_reads A |
| 1819 | 130,00 | 6,35 | 5,42 | 3.386,00 | (@u int)UPDATE lab.CdbWriteOnly SET A = A + 1, B = B + 1, C = C + 1, D = D + 1, E = E + 1, F = F + 1 WHERE Id = ((@u % 200) + 1) |
| ejecuciones | total_ms | cpu_ms | lecturas_logicas | lecturas_fisicas | sql_text |
|---|---|---|---|---|---|
| 1 | 298,56 | 228,39 | 11228 | 217 | SELECT TOP (15) q.query_id, CONVERT(decimal(18,2), SUM(rs.count_executions)) AS ejecuciones, CONVERT(decimal(18,2), SUM(rs.avg_duration * rs.count_executions) / 1000.0) AS duracion_total_ms, CONVERT(decimal(1 |
| 1 | 1,28 | 1,28 | 48 | 0 | SELECT actual_state_desc, desired_state_desc, readonly_reason, current_storage_size_mb, max_storage_size_mb, query_capture_mode_desc, stale_query_threshold_days, size_based_cleanup_mode_desc FROM sys.dat |
| 1 | 1,22 | 1,22 | 149 | 0 | select @sumCountExecutions = sum(case when (execution_type = 0 or @accountAbortedFlag = 1) then count_executions else 0 end), @sumCountAborted = sum(case when execution_type in(3, 4) th |
| 1 | 0,69 | 0,69 | 0 | 0 | SELECT wait_type, waiting_tasks_count, wait_time_ms, signal_wait_time_ms, wait_time_ms - signal_wait_time_ms AS resource_wait_ms FROM sys.dm_os_wait_stats WHERE wait_time_ms > 0 AND waiting_tasks_count > 0 |
| 1 | 0,57 | 0,57 | 192 | 0 | SELECT name, value_in_use, description FROM sys.configurations WHERE name IN ( N'max server memory (MB)', N'min server memory (MB)', N'max degree of parallelism', N'cost threshold for parallelism', N'optimize for |
| 1 | 0,48 | 0,48 | 72 | 0 | SELECT name, value, value_for_secondary FROM sys.database_scoped_configurations WHERE name IN ( N'MAXDOP', N'LEGACY_CARDINALITY_ESTIMATION', N'PARAMETER_SNIFFING', N'QUERY_OPTIMIZER_HOTFIXES', N'ACCELERATED_PLAN_ |
| 1 | 0,29 | 0,29 | 18 | 0 | SELECT name, state_desc, recovery_model_desc, compatibility_level, collation_name, page_verify_option_desc, is_auto_close_on, is_auto_shrink_on, is_auto_create_stats_on, is_auto_update_stats_on, is_auto_update_s |
| 1 | 0,27 | 0,27 | 0 | 0 | SELECT ISNULL(MAX(r.wait_time),0) AS wait_ms, COUNT(*) AS bloqueadas FROM sys.dm_exec_requests r WHERE r.blocking_session_id <> 0 AND DB_NAME(r.database_id) = 'DBA_BI' |
| 1 | 0,19 | 0,19 | 16 | 0 | insert into @intervals(interval_id) select runtime_stats_interval_id from sys.plan_persist_runtime_stats_ |
| 1 | 0,17 | 0,17 | 0 | 0 | SELECT MAX(r.wait_time) AS wait_ms FROM sys.dm_exec_requests r WHERE r.blocking_session_id <> 0 AND DB_NAME(r.database_id) = 'DBA_BI' |
| 1 | 0,10 | 0,10 | 13 | 0 | insert into @plansToCheck(plan_id) select @planId |
| 1 | 0,10 | 0,10 | 0 | 0 | SELECT COUNT(*) AS missing FROM sys.dm_db_missing_index_details WHERE database_id = DB_ID() |
| 1 | 0,10 | 0,10 | 0 | 0 | SELECT COUNT(*) AS missing FROM sys.dm_db_missing_index_details WHERE database_id = DB_ID() |
| planes_un_solo_uso | mb_un_solo_uso | planes_adhoc |
|---|---|---|
| 717 | 75 | 753 |
| objeto | seeks | scans | impacto_pct | igualdad | desigualdad | include_cols |
|---|---|---|---|---|---|---|
| [DBA_BI].[lab].[CdbSeek] | 300 | 0 | 99,60 | [CustomerId] | [OrderDate] |
El DMV ignora indices parecidos que ya existen y no mide el costo de escritura. No cree el indice solo con esta fila.
| esquema | tabla | indice | escrituras |
|---|---|---|---|
| lab | CdbWriteOnly | IX_CdbWrite_F | 130 |
| lab | CdbWriteOnly | IX_CdbWrite_E | 130 |
| lab | CdbWriteOnly | IX_CdbWrite_D | 130 |
| lab | CdbWriteOnly | IX_CdbWrite_C | 130 |
| lab | CdbWriteOnly | IX_CdbWrite_B | 130 |
| lab | CdbWriteOnly | IX_CdbWrite_A | 130 |
Estos contadores vuelven a cero al reiniciar SQL. Uptime actual: 1580 minutos. No borre un indice solo con esta lista.
| esquema | tabla | indice | frag_pct | paginas | accion_sugerida |
|---|---|---|---|---|---|
| lab | CdbFrag | CX_CdbFrag_Sort | 99,10 | 26483 | REBUILD |
Por debajo de 1000 paginas el porcentaje no se informa. REORGANIZE entre 10% y 30%. REBUILD desde 30% en indices grandes. Un REBUILD toma bloqueo de esquema.
| esquema | tabla | estadistica | modificaciones | filas | ratio_pct | last_updated |
|---|---|---|---|---|---|---|
| lab | CdbFrag | CX_CdbFrag_Sort | 80000 | 120000 | 66,70 | 2026-09-22 17:29:59 |
| lab | CdbStale | IX_CdbStale_Code | 2000 | 2000 | 100,00 | 2026-09-22 17:30:13 |
En tablas de 1 millon de filas o mas no haga FULLSCAN como primer paso: SAMPLE suele alcanzar.
| esquema | tabla | indice | fill_factor |
|---|---|---|---|
| lab | CdbSeek | IX_CdbSeek_Status | 30 |
| lab | CdbWriteOnly | IX_CdbWrite_A | 40 |
| lab | CdbWriteOnly | IX_CdbWrite_B | 50 |
| lab | CdbWriteOnly | IX_CdbWrite_C | 60 |
| lab | CdbWriteOnly | IX_CdbWrite_D | 70 |
Un FILLFACTOR bajo suele ser intencional. No lo suba a 90 con un REBUILD si no midio page splits.
| nombre_logico | tipo | tamano_mb | crecimiento | is_percent_growth | growth_pages | physical_name |
|---|---|---|---|---|---|---|
| DBA_BI_log | LOG | 343 | 1MB | False | 128 | C:\SQLLog\DBA_BI_log.ldf |
| DBA_BI | ROWS | 512 | 1MB | False | 128 | C:\SQLData\DBA_BI.mdf |
| vlf_count |
|---|
| 221 |
| tipo | ultimo | horas |
|---|---|---|
| D | 2026-09-10 17:31:01 | 288 |
| name | type_desc | tamano_mb | crecimiento |
|---|---|---|---|
| tempdev | ROWS | 8 | 64MB |
| temp2 | ROWS | 8 | 64MB |
| templog | LOG | 8 | 64MB |
| session_id | blocking_session_id | wait_type | wait_ms | base | status | sql_text |
|---|---|---|---|---|---|---|
| 76 | 74 | LCK_M_X | 144370 | DBA_BI | suspended | (@1 tinyint)UPDATE [lab].[CdbSeek] set [Amount] = [Amount] WHERE [OrderId]=@1 |