Dica do Mês – Microsoft SQL Server 2017 – Relação de Novas colunas internas


Olá pessoal, bom dia.

Tudo bem? Preparado para um mês que esta se iniciando hoje? Se você me perguntar eu ainda não sei te responder pois acordei a pouco(kkkkkk).

Estou iniciando mais um post da sessão Dica do Mês, hoje algo um pouco diferente, não vou apresentar linhas de código, funcionalidades novas ou algo que conheci, muito menos ferramentas. Caso você venha a me perguntar. “Mas Galvão o que exatamente você esta planejando para hoje?”

A minha resposta é simples, vou compartilhar o que descobri de novo no Microsoft SQL Server 2017 que poderá lhe ajudar em momentos de análise de seus dados, bancos de dados e até mesmo do próprio servidor SQL Server. Parece ser algo de outro mundo mas não é, muito pelo contrário, algo que você facilmente poderá encontrar sem muito esforço.

Mas antes de falar do post, vamos destacar um pouco sobre o Microsoft SQL Server 2017. Acredito que você deva saber que no último mês de outubro, a Microsoft realizou mais um lançamento de uma nova versão do Microsoft SQL Server, estou me referindo a versão 2017. Por acaso você estão utilizando esta nova versão? Caso ainda não tenha feito, aproveite e faça agora mesmo acessando o link: https://www.microsoft.com/en-us/sql-server/sql-server-2017.

Se você, assim como eu realizou o download no mesmo dia do lançamento, ou seja, dia 02/10, pode ter um certo tempo para notar que a cada nova versão, o produto esta evoluindo, tanto no seu processo de instalação que realmente é fantástico e muito prático, como também, na quantidade de recursos, funcionalidades e componentes internos apresentados a partir desta da versão 2017.

Foi pensando neste cenário que o post da sessão Dica do Mês foi concebido, apresentar um pouco das novidades internas que o Microsoft SQL Server 2017 possuí em comparação com seus antecessores.

Sendo assim, seja bem vindo ao post – Dica do Mês – Microsoft SQL Server 2017 – Relação de Novas colunas internas.

Você vai descobrir o conjunto de novos dados técnicos catalogados pelo SQL Server 2017 seremos capazes de obter em real-time……


Introdução

Afim de mostrar o que de novo foi adicionado a partir da versão 2017, decidi identificar o que internamente existe de diferente que não tínhamos na versão 2016 ou anteriores, desta forma, escolhi fazer um comparativo entre a versão 2017 e a versão 2016 SP1, lançado no último mês de abril.

Foi idealizando este cenário, que fiz a simples escolha de utilizar uma velha conhecida system view denominada sys.all_columns presente a partir do Microsoft SQL Server desde a versão 2005. Tenho quase a certeza que você conhece esta system view! Ainda não, poxa vida, isso não é um pecado, mas é algo que talvez possa lhe ser útil.

Basicamente a sys.all_columns, como boa parte das visões de sistemas, apresentam um conjunto de dados técnicos catalogados pelo Microsoft SQL Server afim de ajudar internamente o funcionamento lógico e relacional do produto, mas também, como um guia para nós profissionais de bancos de dados, quanto temos a necessidade de analisar ou identificar dados técnicos, objetos, recursos ou funcionalidades oriundas do SQL Server.

Através desta DMV, temos a capacidade de obter a relação completa de colunas que formam nossos objetos e também os próprios objetos criados pelo SQL Server no processo da instalação ou durante nossas atividades, o que me permitiu identificar os novas colunas internas adicionadas na versão 2017 categorizadas da seguinte maneira:

  • Internal Tables;
  • InLine Table-Valued Function;
  • System Tables;
  • System Views; e
  • User Tables.

A seguir apresento a relação completa das novas colunas internadas adicionadas a partir do Microsoft SQL Server 2017:

Internal Tables

  • _trusted_assemblies.create_date
  • _trusted_assemblies.created_by
  • _trusted_assemblies.description
  • _trusted_assemblies.hash
  • plan_persist_query.query_flags
  • plan_persist_query_hints.batch_sql_handle
  • plan_persist_query_hints.comment
  • plan_persist_query_hints.context_settings_id
  • plan_persist_query_hints.last_query_hint_failure_reason
  • plan_persist_query_hints.object_id
  • plan_persist_query_hints.query_hash
  • plan_persist_query_hints.query_hint_failure_count
  • plan_persist_query_hints.query_hint_id
  • plan_persist_query_hints.query_hints_flags
  • plan_persist_query_hints.query_hints
  • plan_persist_query_hints.query_id
  • plan_persist_query_hints.query_param_type
  • plan_persist_query_hints.statement_sql_handle
  • plan_persist_query_template_parameterization.comment
  • plan_persist_query_template_parameterization.last_parameterization_failure_reason
  • plan_persist_query_template_parameterization.parameterization_failure_count
  • plan_persist_query_template_parameterization.query_param_type
  • plan_persist_query_template_parameterization.query_template_flags
  • plan_persist_query_template_parameterization.query_template_hash
  • plan_persist_query_template_parameterization.query_template_id
  • plan_persist_query_template_parameterization.query_template
  • plan_persist_query_text.query_template_hash
  • plan_persist_wait_stats.count_executions
  • plan_persist_wait_stats.execution_type
  • plan_persist_wait_stats.last_query_wait_time_ms
  • plan_persist_wait_stats.max_query_wait_time_ms
  • plan_persist_wait_stats.min_query_wait_time_ms
  • plan_persist_wait_stats.plan_id
  • plan_persist_wait_stats.runtime_stats_interval_id
  • plan_persist_wait_stats.sumsquare_query_wait_time_ms
  • plan_persist_wait_stats.total_query_wait_time_ms
  • plan_persist_wait_stats.wait_category
  • plan_persist_wait_stats.wait_stats_id

Inline table-valued functions

  • dm_db_log_info.database_id
  • dm_db_log_info.file_id
  • dm_db_log_info.vlf_active
  • dm_db_log_info.vlf_begin_offset
  • dm_db_log_info.vlf_create_lsn
  • dm_db_log_info.vlf_first_lsn
  • dm_db_log_info.vlf_parity
  • dm_db_log_info.vlf_sequence_number
  • dm_db_log_info.vlf_size_mb
  • dm_db_log_info.vlf_status
  • dm_db_log_stats.active_log_size_mb
  • dm_db_log_stats.active_vlf_count
  • dm_db_log_stats.current_vlf_sequence_number
  • dm_db_log_stats.current_vlf_size_mb
  • dm_db_log_stats.database_id
  • dm_db_log_stats.log_backup_lsn
  • dm_db_log_stats.log_backup_time
  • dm_db_log_stats.log_checkpoint_lsn
  • dm_db_log_stats.log_end_lsn
  • dm_db_log_stats.log_min_lsn
  • dm_db_log_stats.log_recovery_lsn
  • dm_db_log_stats.log_recovery_size_mb
  • dm_db_log_stats.log_since_last_checkpoint_mb
  • dm_db_log_stats.log_since_last_log_backup_mb
  • dm_db_log_stats.log_truncation_holdup_reason
  • dm_db_log_stats.recovery_model
  • dm_db_log_stats.recovery_vlf_count
  • dm_db_log_stats.total_log_size_mb
  • dm_db_log_stats.total_vlf_count
  • dm_os_enumerate_filesystem.creation_time
  • dm_os_enumerate_filesystem.file_or_directory_name
  • dm_os_enumerate_filesystem.full_filesystem_path
  • dm_os_enumerate_filesystem.has_integrity_stream
  • dm_os_enumerate_filesystem.is_directory
  • dm_os_enumerate_filesystem.is_hidden
  • dm_os_enumerate_filesystem.is_read_only
  • dm_os_enumerate_filesystem.is_sparse
  • dm_os_enumerate_filesystem.is_system
  • dm_os_enumerate_filesystem.is_temporary
  • dm_os_enumerate_filesystem.last_access_time
  • dm_os_enumerate_filesystem.last_write_time
  • dm_os_enumerate_filesystem.level
  • dm_os_enumerate_filesystem.parent_directory
  • dm_os_enumerate_filesystem.size_in_bytes
  • dm_os_file_exists.file_exists
  • dm_os_file_exists.file_is_a_directory
  • dm_os_file_exists.parent_directory_exists
  • dm_sql_referenced_entities.is_incomplete
  • fn_full_dblog.AllocUnitId
  • fn_full_dblog.AllocUnitName
  • fn_full_dblog.Article ID
  • fn_full_dblog.Begin Time
  • fn_full_dblog.Beginlog Status
  • fn_full_dblog.Bulk allocated extent count
  • fn_full_dblog.Bulk allocated extent ids
  • fn_full_dblog.Bulk allocation first IAM Page ID
  • fn_full_dblog.Bulk AllocUnitId
  • fn_full_dblog.Bulk RowsetId
  • fn_full_dblog.Byte Offset
  • fn_full_dblog.Bytes Freed
  • fn_full_dblog.Checkpoint Begin
  • fn_full_dblog.Checkpoint End
  • fn_full_dblog.CHKPT Begin DB Version
  • fn_full_dblog.CHKPT End DB Version
  • fn_full_dblog.CI Index Id
  • fn_full_dblog.CI Table Id
  • fn_full_dblog.Column Offset
  • fn_full_dblog.Command Type
  • fn_full_dblog.Command
  • fn_full_dblog.Compression Info
  • fn_full_dblog.Compression Log Type
  • fn_full_dblog.Context
  • fn_full_dblog.CopyVerionInfo Source Page Id
  • fn_full_dblog.CopyVerionInfo Source Page LSN
  • fn_full_dblog.CopyVerionInfo Source Slot Count
  • fn_full_dblog.CopyVerionInfo Source Slot Id
  • fn_full_dblog.Current LSN
  • fn_full_dblog.Database Name
  • fn_full_dblog.Description
  • fn_full_dblog.Dirty Pages
  • fn_full_dblog.End AGE
  • fn_full_dblog.End Time
  • fn_full_dblog.File ID
  • fn_full_dblog.File Status
  • fn_full_dblog.FileGroup ID
  • fn_full_dblog.Flag Bits
  • fn_full_dblog.Flags
  • fn_full_dblog.Format LSN
  • fn_full_dblog.InvalidateCache Id
  • fn_full_dblog.InvalidateCache keys
  • fn_full_dblog.Last Distributed Backup End LSN
  • fn_full_dblog.Last Distributed End LSN
  • fn_full_dblog.Lock Information
  • fn_full_dblog.Log Record Fixed Length
  • fn_full_dblog.Log Record Length
  • fn_full_dblog.Log Record
  • fn_full_dblog.Log Reserve
  • fn_full_dblog.LogBlockGeneration
  • fn_full_dblog.Logical Name
  • fn_full_dblog.LSN before writes
  • fn_full_dblog.Mark Name
  • fn_full_dblog.Master DBID
  • fn_full_dblog.Master XDESID
  • fn_full_dblog.Max XDESID
  • fn_full_dblog.Meta Status
  • fn_full_dblog.Minimum LSN
  • fn_full_dblog.Modify Size
  • fn_full_dblog.New Size
  • fn_full_dblog.New Split Page
  • fn_full_dblog.New Value
  • fn_full_dblog.NewAllocUnitId
  • fn_full_dblog.Next Replicated End LSN
  • fn_full_dblog.Num Elements
  • fn_full_dblog.Num Transactions
  • fn_full_dblog.Number of Locks
  • fn_full_dblog.Offset in Row
  • fn_full_dblog.Offset
  • fn_full_dblog.Old Size
  • fn_full_dblog.Old Value
  • fn_full_dblog.Oldest Active LSN
  • fn_full_dblog.Oldest Active Transaction ID
  • fn_full_dblog.Oldest Replicated Begin LSN
  • fn_full_dblog.Operation
  • fn_full_dblog.Page ID
  • fn_full_dblog.PageFormat FormatOption
  • fn_full_dblog.PageFormat PageFlags
  • fn_full_dblog.PageFormat PageLevel
  • fn_full_dblog.PageFormat PageStat
  • fn_full_dblog.PageFormat PageType
  • fn_full_dblog.Pages Written
  • fn_full_dblog.Parent Transaction ID
  • fn_full_dblog.Partial Status
  • fn_full_dblog.PartitionId
  • fn_full_dblog.Physical Name
  • fn_full_dblog.Prepare Time
  • fn_full_dblog.Preplog Begin LSN
  • fn_full_dblog.Previous LSN
  • fn_full_dblog.Previous Page LSN
  • fn_full_dblog.Previous Savepoint
  • fn_full_dblog.Publication ID
  • fn_full_dblog.Repl CSN
  • fn_full_dblog.Repl Epoch
  • fn_full_dblog.Repl Flags
  • fn_full_dblog.Repl Min Hold LSN
  • fn_full_dblog.Repl Msg
  • fn_full_dblog.Repl Partition ID
  • fn_full_dblog.Repl Source Commit Time
  • fn_full_dblog.Replicated Records
  • fn_full_dblog.Rowbits Bit Count
  • fn_full_dblog.Rowbits Bit Value
  • fn_full_dblog.Rowbits First Bit
  • fn_full_dblog.RowFlags
  • fn_full_dblog.RowLog Contents 0
  • fn_full_dblog.RowLog Contents 1
  • fn_full_dblog.RowLog Contents 2
  • fn_full_dblog.RowLog Contents 3
  • fn_full_dblog.RowLog Contents 4
  • fn_full_dblog.RowLog Contents 5
  • fn_full_dblog.Rows Deleted
  • fn_full_dblog.RowsetId
  • fn_full_dblog.Savepoint Name
  • fn_full_dblog.Server Name
  • fn_full_dblog.Server UID
  • fn_full_dblog.Slot ID
  • fn_full_dblog.SPID
  • fn_full_dblog.Tag Bits
  • fn_full_dblog.Text Size
  • fn_full_dblog.TextPtr
  • fn_full_dblog.Transaction Begin
  • fn_full_dblog.Transaction ID
  • fn_full_dblog.Transaction Name
  • fn_full_dblog.Transaction SID
  • fn_full_dblog.Virtual Clock
  • fn_full_dblog.VLFs added
  • fn_full_dblog.Xact ID
  • fn_full_dblog.Xact Node ID
  • fn_full_dblog.Xact Node Local ID
  • fn_full_dblog.Xact Type
  • fn_get_audit_file.affected_rows
  • fn_get_audit_file.application_name
  • fn_get_audit_file.client_ip
  • fn_get_audit_file.duration_milliseconds
  • fn_get_audit_file.response_rows
  • fn_xe_file_target_read_file.timestamp_utc

System Tables

  • syscscolsegments.container_id
  • syscsdictionaries.container_id

User Tables

  • MSreplication_options.install_failures
  • MSreplication_options.major_version
  • MSreplication_options.minor_version
  • MSreplication_options.optname
  • MSreplication_options.revision
  • MSreplication_options.value
  • spt_monitor.connections
  • spt_monitor.cpu_busy
  • spt_monitor.idle
  • spt_monitor.io_busy
  • spt_monitor.lastrun
  • spt_monitor.pack_errors
  • spt_monitor.pack_received
  • spt_monitor.pack_sent
  • spt_monitor.total_errors
  • spt_monitor.total_read
  • spt_monitor.total_write

Views

  • all_columns.graph_type_desc
  • all_columns.graph_type
  • availability_groups.cluster_type_desc
  • availability_groups.cluster_type
  • availability_groups.required_synchronized_secondaries_to_commit
  • availability_groups.sequence_number
  • columns.graph_type_desc
  • columns.graph_type
  • computed_columns.graph_type_desc
  • computed_columns.graph_type
  • database_automatic_tuning_mode.actual_state_desc
  • database_automatic_tuning_mode.actual_state
  • database_automatic_tuning_mode.desired_state_desc
  • database_automatic_tuning_mode.desired_state
  • database_automatic_tuning_options.actual_state_desc
  • database_automatic_tuning_options.actual_state
  • database_automatic_tuning_options.desired_state_desc
  • database_automatic_tuning_options.desired_state
  • database_automatic_tuning_options.name
  • database_automatic_tuning_options.reason_desc
  • database_automatic_tuning_options.reason
  • database_credentials.principal_id
  • database_files.is_persistent_log_buffer
  • database_query_store_options.wait_stats_capture_mode_desc
  • database_query_store_options.wait_stats_capture_mode
  • database_scoped_configurations.is_value_default
  • database_scoped_credentials.principal_id
  • databases.is_temporal_history_retention_enabled
  • dm_db_column_store_row_group_physical_stats.closed_time
  • dm_db_column_store_row_group_physical_stats.created_time
  • dm_db_column_store_row_group_physical_stats.deleted_rows
  • dm_db_column_store_row_group_physical_stats.delta_store_hobt_id
  • dm_db_column_store_row_group_physical_stats.generation
  • dm_db_column_store_row_group_physical_stats.has_vertipaq_optimization
  • dm_db_column_store_row_group_physical_stats.index_id
  • dm_db_column_store_row_group_physical_stats.object_id
  • dm_db_column_store_row_group_physical_stats.partition_number
  • dm_db_column_store_row_group_physical_stats.row_group_id
  • dm_db_column_store_row_group_physical_stats.size_in_bytes
  • dm_db_column_store_row_group_physical_stats.state_desc
  • dm_db_column_store_row_group_physical_stats.state
  • dm_db_column_store_row_group_physical_stats.total_rows
  • dm_db_column_store_row_group_physical_stats.transition_to_compressed_state_desc
  • dm_db_column_store_row_group_physical_stats.transition_to_compressed_state
  • dm_db_column_store_row_group_physical_stats.trim_reason_desc
  • dm_db_column_store_row_group_physical_stats.trim_reason
  • dm_db_file_space_usage.modified_extent_page_count
  • dm_db_mirroring_connections.address
  • dm_db_tuning_recommendations.details
  • dm_db_tuning_recommendations.execute_action_duration
  • dm_db_tuning_recommendations.execute_action_initiated_by
  • dm_db_tuning_recommendations.execute_action_initiated_time
  • dm_db_tuning_recommendations.execute_action_start_time
  • dm_db_tuning_recommendations.is_executable_action
  • dm_db_tuning_recommendations.is_revertable_action
  • dm_db_tuning_recommendations.last_refresh
  • dm_db_tuning_recommendations.name
  • dm_db_tuning_recommendations.reason
  • dm_db_tuning_recommendations.revert_action_duration
  • dm_db_tuning_recommendations.revert_action_initiated_by
  • dm_db_tuning_recommendations.revert_action_initiated_time
  • dm_db_tuning_recommendations.revert_action_start_time
  • dm_db_tuning_recommendations.score
  • dm_db_tuning_recommendations.state
  • dm_db_tuning_recommendations.type
  • dm_db_tuning_recommendations.valid_since
  • dm_db_xtp_checkpoint_internals.checkpoint_id
  • dm_db_xtp_checkpoint_internals.checkpoint_timestamp
  • dm_db_xtp_checkpoint_internals.is_synchronized
  • dm_db_xtp_checkpoint_internals.last_segment_lsn
  • dm_db_xtp_checkpoint_internals.recovery_lsn
  • dm_exec_query_stats.last_columnstore_segment_reads
  • dm_exec_query_stats.last_columnstore_segment_skips
  • dm_exec_query_stats.max_columnstore_segment_reads
  • dm_exec_query_stats.max_columnstore_segment_skips
  • dm_exec_query_stats.min_columnstore_segment_reads
  • dm_exec_query_stats.min_columnstore_segment_skips
  • dm_exec_query_stats.total_columnstore_segment_reads
  • dm_exec_query_stats.total_columnstore_segment_skips
  • dm_exec_requests.is_resumable
  • dm_os_enumerate_fixed_drives.drive_type_desc
  • dm_os_enumerate_fixed_drives.drive_type
  • dm_os_enumerate_fixed_drives.fixed_drive_path
  • dm_os_enumerate_fixed_drives.free_space_in_bytes
  • dm_os_host_info.host_distribution
  • dm_os_host_info.host_platform
  • dm_os_host_info.host_release
  • dm_os_host_info.host_service_pack_level
  • dm_os_host_info.host_sku
  • dm_os_host_info.os_language_version
  • dm_os_memory_objects.partition_type_desc
  • dm_os_nodes.cpu_count
  • dm_os_sys_info.cores_per_socket
  • dm_os_sys_info.numa_node_count
  • dm_os_sys_info.process_physical_affinity
  • dm_os_sys_info.socket_count
  • dm_os_worker_local_storage.gq_address
  • dm_tran_global_transactions.max_csn
  • dm_tran_global_transactions_enlistments.snapshot_timestamp
  • dm_tran_global_transactions_log.commit_timestamp
  • dm_tran_version_store_space_usage.database_id
  • dm_tran_version_store_space_usage.reserved_page_count
  • dm_tran_version_store_space_usage.reserved_space_kb
  • dm_xe_session_targets.bytes_written
  • dm_xe_sessions.buffer_full_count
  • dm_xe_sessions.buffer_processed_count
  • dm_xe_sessions.total_bytes_generated
  • external_libraries.external_library_id
  • external_libraries.language
  • external_libraries.name
  • external_libraries.principal_id
  • external_libraries.scope_desc
  • external_libraries.scope
  • external_library_files.content
  • external_library_files.external_library_id
  • external_library_files.platform_desc
  • external_library_files.platform
  • hash_indexes.auto_created
  • hash_indexes.is_ignored_in_optimization
  • identity_columns.graph_type_desc
  • identity_columns.graph_type
  • index_resumable_operations.index_id
  • index_resumable_operations.last_max_dop_used
  • index_resumable_operations.last_pause_time
  • index_resumable_operations.name
  • index_resumable_operations.object_id
  • index_resumable_operations.page_count
  • index_resumable_operations.partition_number
  • index_resumable_operations.percent_complete
  • index_resumable_operations.sql_text
  • index_resumable_operations.start_time
  • index_resumable_operations.state_desc
  • index_resumable_operations.state
  • index_resumable_operations.total_execution_time
  • indexes.auto_created
  • indexes.is_ignored_in_optimization
  • indexes.suppress_dup_key_messages
  • key_constraints.is_enforced
  • masked_columns.graph_type_desc
  • masked_columns.graph_type
  • master_files.is_persistent_log_buffer
  • query_store_plan.plan_forcing_type_desc
  • query_store_plan.plan_forcing_type
  • query_store_runtime_stats.avg_log_bytes_used
  • query_store_runtime_stats.avg_num_physical_io_reads
  • query_store_runtime_stats.avg_tempdb_space_used
  • query_store_runtime_stats.last_log_bytes_used
  • query_store_runtime_stats.last_num_physical_io_reads
  • query_store_runtime_stats.last_tempdb_space_used
  • query_store_runtime_stats.max_log_bytes_used
  • query_store_runtime_stats.max_num_physical_io_reads
  • query_store_runtime_stats.max_tempdb_space_used
  • query_store_runtime_stats.min_log_bytes_used
  • query_store_runtime_stats.min_num_physical_io_reads
  • query_store_runtime_stats.min_tempdb_space_used
  • query_store_runtime_stats.stdev_log_bytes_used
  • query_store_runtime_stats.stdev_num_physical_io_reads
  • query_store_runtime_stats.stdev_tempdb_space_used
  • query_store_wait_stats.avg_query_wait_time_ms
  • query_store_wait_stats.execution_type_desc
  • query_store_wait_stats.execution_type
  • query_store_wait_stats.last_query_wait_time_ms
  • query_store_wait_stats.max_query_wait_time_ms
  • query_store_wait_stats.min_query_wait_time_ms
  • query_store_wait_stats.plan_id
  • query_store_wait_stats.runtime_stats_interval_id
  • query_store_wait_stats.stdev_query_wait_time_ms
  • query_store_wait_stats.total_query_wait_time_ms
  • query_store_wait_stats.wait_category_desc
  • query_store_wait_stats.wait_category
  • query_store_wait_stats.wait_stats_id
  • sequences.last_used_value
  • spatial_indexes.auto_created
  • spatial_indexes.is_ignored_in_optimization
  • spt_values.high
  • spt_values.low
  • spt_values.name
  • spt_values.number
  • spt_values.status
  • spt_values.type
  • syscscontainers.blob_container_id
  • syscscontainers.blob_container_type
  • syscscontainers.blob_container_url
  • system_columns.graph_type_desc
  • system_columns.graph_type
  • tables.history_retention_period_unit_desc
  • tables.history_retention_period_unit
  • tables.history_retention_period
  • tables.is_edge
  • tables.is_node
  • trusted_assemblies.create_date
  • trusted_assemblies.created_by
  • trusted_assemblies.description
  • trusted_assemblies.hash
  • xml_indexes.auto_created
  • xml_indexes.is_ignored_in_optimization

Importante: Vale ressaltar que estas novas colunas estão compondo o conjunto atual de recursos internos já existentes no Microsoft SQL Server, não estou me referindo a novas Internal Tables, DMVs ou Views adicionadas ao produto na versão 2017.

Com isso chegamos ao final de mais um post da sessão Dica do Mês, espero que você tenha gostado, então do meu tradicional encerramento, quero destacar em algumas destas novas colunas serão destaco em posts futuros do meu blog.


Referências

https://technet.microsoft.com/pt-br/library/ms178596(v=sql.110).aspx

https://technet.microsoft.com/pt-br/library/ms188021(v=sql.110).aspx

https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-all-columns-transact-sql

Posts Anteriores

https://pedrogalvaojunior.wordpress.com/2017/08/26/dica-do-mes-simulando-a-insercao-de-uma-massa-de-dados-aleatoria/

https://pedrogalvaojunior.wordpress.com/2017/05/23/conhecendo-e-aplicando-o-uso-de-atualizacao-de-estatisticas-incrementais/

https://pedrogalvaojunior.wordpress.com/2017/04/13/dica-do-mes-microsoft-sql-server-identificando-as-transacoes-que-estao-utilizando-o-transact-log/

https://pedrogalvaojunior.wordpress.com/2017/03/01/dica-do-mes-microsoft-sql-server-2016-sp1-novo-argumento-use-hint-disponivel-para-query-hints/

https://pedrogalvaojunior.wordpress.com/2017/01/16/dica-do-mes-conhecendo-a-nova-dmf-sys-dm_exec_input_buffer-no-microsoft-sql-server-2016/

Conclusão

A cada versão do Microsoft SQL Server evolui, a gama de dados técnicos catalogados que nos permitem analisar e ajudar em possíveis cenários de administração ou tomadas de decisão cresce de forma exponencial, com isso, temos um conjunto inimaginável de possibilidades e alternativas que nos possibilitam superior nossos desafios.

Esse é o Microsoft SQL Server ainda mais poderoso na versão 2017.

 

Agradecimentos

Mais uma vez obrigado por sua visita, agradeço sua atenção, fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Um forte abraço, nos encontramos no próximo post a ser publicado no mês de janeiro de 2018.

Vai SQL Server, Vai SQL Server…..

Abraços.

Anúncios

Dica do Mês – Simulando a inserção de uma massa de dados aleatória


Olá pessoal, boa tarde.

Estou retornando com mais um post da sessão Dica do Mês, onde hoje vou compartilhar algo que poderá lhe ajudar de maneira simples e direta em suas atividades relacionadas a simulação de manipulação de dados no Microsoft SQL Server.

Acredito que em algum momento você já teve a necessidade de inserir dezenas, centenas ou até mesmo milhares de linhas em uma determinada tabela em seus bancos de dados, se você ainda não passou por esta necessidade pode ter a certeza que em algum momento isso poderá lhe acontecer.

Pensando justamente nisso, vou compartilhar no post de hoje um script de minha autoria que utilizo justamente para realizar esta inserção de dados aleatórios em uma tabela específica sem levar em consideração a qualidade e veracidade dos dados, como também regras de integridade referencial ou normalização.

Sendo assim, seja bem vindo ao post – Dica do Mês – Simulando a inserção de uma massa de dados aleatória.

Bom divertimento……


Introdução

A necessidade de se trabalhar com um volume considerável de dados pode ser algo bastante comum para muitos profissionais de bancos de dados, para outros nem tanto.

Este pode parecer um cenário bastante complexo, que venha a exigir um grande conhecimento técnico ou até mesmo o uso de ferramentas de terceiros para tal finalidade. Mas na sua grande maioria os recursos existentes no próprio Microsoft SQL Server nos permite criar scripts ou blocos de códigos capazes de realizar tão procedimento sem requerer a obtenção ou exigência de um alto nível de conhecimento.

Nosso Cenário

Afim de tentar ilustrar como podemos realizar este tipo de procedimento em um ambiente de banco de dados, vamos trabalhar com um ambiente de banco de dados bastante simples e que apresenta baixa complexidade.

Nosso ambiente será forma por uma única tabela denominada MassaDeDados, composta pela seguinte estrutura de colunas:

  • Codigo;
  • ClienteID;
  • VendedorID;
  • Quantidade;
  • Valor; e
  • Data

A coluna denominada Codigo será definida como nossa coluna chave primária artificial numerada de forma sequência próprio SQL Server, tento como finalidade evitar a duplicação de registros e principalmente ser utilizada como atributo de busca e pesquisa de nossos dados. As demais colunas estarão sendo utilizadas como atributos complementares para ilustrar a capacidade de geração de dados aleatórios e posteriormente inseridos em nossa tabela MassaDeDados.

A seguir apresento o Bloco de Código 1, utilizado para criação da tabela MassaDeDados:

— Bloco de Código 1 —

Create Table MassaDeDados
(Codigo int IDENTITY(1,1) NOT NULL Primary Key,
ClienteId int NOT NULL,
VendedorId varchar(10) NOT NULL,
Quantidade smallint NOT NULL,
Valor numeric(18, 2) NOT NULL,
Data date NOT NULL)
Go

Perfeito, note que este bloco de código é bastante simples, nosso próximo passo será justamente trabalhar com o bloco de código que nos permitirá gerar o volume de dados aleatórios inseridos na sequência dentro da tabela MassaDeDados, para tal procedimentos vamos utilizar o Bloco de Código 2 apresentado abaixo:

— Bloco de Código 2 —

Declare @Texto Char(130), @Posicao TinyInt, @ContadorLinhas Int

Set @Texto = ‘0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ\_abcdefghijklmnopqrstuvwxyzŽŸ¡ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝàáâãäåæçèéêëìíîïðñòóôõöùúûüýÿ’ — Existem 130 caracteres neste texto —

Set @ContadorLinhas = Rand()*100000 — Definir a quantidade de linhas para serem inseridas —

While (@ContadorLinhas >=1)
Begin

Set @Posicao=Rand()*130

 

If @Posicao <=125
Begin
Insert Into MassaDeDados (ClienteId, VendedorId, Quantidade, Valor, Data)
Values(@ContadorLinhas,
Concat(SubString(@Texto,@Posicao+2,2),SubString(@Texto,@Posicao-4,4),SubString(@Texto,@Posicao+2,4)),
Rand()*1000,
Rand()*100+5,
DATEADD(d, 1000*Rand() ,GetDate()))

End
Else
Begin
Insert Into MassaDeDados (ClienteID, VendedorID, Quantidade, Valor, Data)
Values(@ContadorLinhas,
Concat(SubString(@Texto,@Posicao-10,1),SubString    (@Texto,@Posicao+4,6),SubString(@Texto,@Posicao-12,3)),
Rand()*1000,
Rand()*100+5,
DATEADD(d, 1000*Rand() ,GetDate()))

End

Set @ContadorLinhas = @ContadorLinhas – 1
End

Observação: Note que estou utilizando a função Concat() para realizar a concatenação dos dados sem a necessidade de conversão implícita, sendo esta função recurso adicionado a partir da versão 2012 do SQL Server, caso você esteja utilizando uma versão anterior remova a função Concat() e aplique a concatenação utilizando o operador de soma.

Agora basta executar o bloco de código e verificar o resultado obtido, no meu caso após a execução deste mesmo exemplo obtive o resultado apresentado pela Figura 1 apresentada abaixo:

Figura 1 – Massa de Dados aleatórios inseridos na tabela MassaDeDados.

Observando a Figura 1, torna-se fácil analisar o conjunto de dados aleatórios inseridos em cada coluna de nossa tabela, como também, a quantidade de linhas inseridas sendo um total de 41.857 linhas de registros.

Inicialmente o tamanho do bloco de código poderá parecer complexo ou até mesmo confuso, mas na verdade não é bem assim, o grande segredo esta justamente no uso da variável @Texto que apresenta um conjunto de 130 caracteres que podemos utilizar no processo de geração do nosso volume aleatório de dados.

Outro fator muito importante é o uso da função RAND() que nos possibilidade o sorteio de números decimais, algo que ajuda bastante quando queremos trabalhar com faixas de valores distintos.

Vale ressaltar que a função RAND trabalhar com valores decimais, para que seja possível realizar o sorteio aleatório de números e depois transformar em números inteiros temos a necessidade de utilizar variáveis que trabalhem com tipos de dados inteiros, neste caso: TinyInt, SmallInt, Int ou BigInt, caso contrário os valores retornados por esta função será sempre tratados e apresentados no formato de números decimais.

Com isso chegamos ao final de mais um post da sessão Dica do Mês, espero que você tenha gostado.

Referências

https://technet.microsoft.com/pt-br/library/ms177610(v=sql.105).aspx

https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-types-transact-sql

https://docs.microsoft.com/en-us/sql/t-sql/language-elements/declare-local-variable-transact-sql

https://technet.microsoft.com/pt-br/library/hh231515(v=sql.110).aspx

Posts Anteriores

https://pedrogalvaojunior.wordpress.com/2017/05/23/conhecendo-e-aplicando-o-uso-de-atualizacao-de-estatisticas-incrementais/

https://pedrogalvaojunior.wordpress.com/2017/04/13/dica-do-mes-microsoft-sql-server-identificando-as-transacoes-que-estao-utilizando-o-transact-log/

https://pedrogalvaojunior.wordpress.com/2017/03/01/dica-do-mes-microsoft-sql-server-2016-sp1-novo-argumento-use-hint-disponivel-para-query-hints/

https://pedrogalvaojunior.wordpress.com/2017/01/16/dica-do-mes-conhecendo-a-nova-dmf-sys-dm_exec_input_buffer-no-microsoft-sql-server-2016/

Conclusão

Em diversos cenários temos a necessidade de imaginar diversas possibilidades para se obter a solução de um problema que inicialmente se apresenta com algo de outro mundo, por outro lado realizando uma análise com calma e simulando diversos cenários esta possível solução tão “misteriosa” e “complexa” pode estar na frente de nossos olhos.

No post de hoje isso não foi diferente, realizar a inserção de um volume aleatório e fictício de dados dentro do Microsoft SQL Server pode ser feito de forma bastante simples e prática, sem requerer qualquer tipo ferramentas adicionais ou conhecimento de alto nível.

Agradecimentos

Mais uma vez obrigado por sua visita, agradeço sua atenção, fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Um forte abraço, nos encontramos no próximo post a ser publicado no mês de outubro.

Valeu….

Dica do Mês – Conhecendo e aplicando o uso de atualização de estatísticas incrementais


Muito boa tarde pessoal, salve, salve comunidade e amantes de banco de dados.

Tudo bem com vocês? Estou aqui mais uma vez em um novo post do meu blog na sessão Dica do Mês, hoje falando de um assunto que até alguns dias atrás eu sinceramente nunca havia feito uso, mas com base em um post publicado do Ahmad Yaseen no MSSQLTips.com, acabou me servindo como fonte de inspiração para elaborar e compartilhar este post com vocês.

Antes de começarmos a falar sobre o post de hoje, nada mais justo começar agradecendo como de costume a você está aqui neste momento acessando meu blog. Espero que possa ter encontrado o que precisa, bem como, esteja gostando do conteúdo publicado, fique a vontade para entrar em contato expressando suas opiniões e demais pensamentos.

Dando continuidade, vamos conhecer um recurso adicionado na versão 2014 do Microsoft SQL Server a partir do Service Pack 2 e mantido no Microsoft SQL Server 2016 SP1 conhecido como Estatísticas Incrementais ou Incremental Statistics, pode parecer estranho o nome, mas é exatamente isso que este recurso permite, realizar o processo de atualização de estatísticas de maneira incremental, ou para muitos incrementar o processo de atualização de estatísticas aplicadas aos nossos bancos de dados e seus respectivos objetos.

Parece ser coisa de louco isso, mas posso garantir que não é, absolutamente é algo totalmente viável e aplicável a qualquer ambiente que se faça uso do Microsoft SQL Server em conjunto com as funções e scheme de particionamento de dados.

E ai esta curioso para saber um pouco sobre este recurso?

Eu estou, sendo assim, vamos em frente, seja bem vindo ao post Dica do Mês – Conhecendo e aplicando o uso de atualização de estatísticas incrementais.

Seguindo….


Introdução

O otimizador de consultas do Microsoft SQL Server depende fortemente das estatísticas na geração a execução de plano de consulta mais eficiente. Estas estatísticas fornecem ao otimizador a distribuição dos valores de colunas na tabela e o número de linhas, também chamada a cardinalidade que resultará da consulta.

A ausência destas estatísticas, ou a existência de estatísticas desatualizadas, proporciona a ocorrência de querys consideradas lentas, neste sentido, o otimizador de consulta “query optimizer” acaba sendo obrigado a utilizar estatísticas imprecisas para criar o plano de execução, que pode ser considerado um plano não ideal para executar a consulta neste caso.

O SQL Server geralmente faz o seu trabalho em manter estas estatísticas atualizadas, mas como um administrador de banco de dados, você deve fazer seu trabalho, em alguns casos, atualizando as estatísticas manualmente. Atualizar estatísticas manualmente em tabelas grandes pode ser como um grande desafio, bem como, em tabelas pequenas pode-se imaginar que a estatística já esteja atualizada, o que em alguns cenários isso acaba não ocorrendo.

Um dos cenários mais impactados pelo uso de estatísticas desatualizadas ou atualizadas parcialmente são as tabelas particionadas. Como destacado anteriormente através do uso das funções de particionamento de dados introduzido no Microsoft SQL Server 2008, temos a capacidade de distribuir nossos dados em partições “pequenos fatias de armazenamento de dados” que nos possibilitar distribuir respectivos valores com base em uma função que análise e identifica o local de armazenamento do mesmo.

Para este tipo de ambiente, o uso de estatísticas como mecanismo para auxiliar no obtenção mais rápida do dado, pode apresentar simultaneamente o papel de herói como também de vilão, isso pode parecer meio confusão, mas não é! Basicamente quando trabalhamos com estatísticas acreditamos que sempre teremos todas as informações armazenados no histograma atualizadas de forma automática de maneira mais precisa possível, algo que não acontece exatamente desta maneira quando trabalhando com particionamento de dados.

Uma das situações mais comuns quando se uso particionamento de dados é a possibilidade de ocorrer a atualização de estatísticas de maneira parcial, ou seja, apena um partição de todo estrutura de partições acaba tendo suas informações de estatísticas atualizadas, o que poderá provocar uma alteração no plano de execução ou a possibilidade de criação de um plano incoerente.

Sabendo desta possibilidade e comportamento, o time de engenheiros e desenvolvedores do Microsoft SQL Server, implementou a partir da versão 2014 SP1 as Estatísticas Incrementais, funcionalidade que nos permite justamente contornar este tipo de situação.

Estatísticas Incrementais – Incremental Statistics

As estatísticas Incrementais, ajudam na atualização de estatísticas para apenas a partição ou partições que você escolher. Em vez de analisar e varrer a tabela inteira para atualizar as estatísticas, a partição selecionada será verificada somente para a atualização, reduzindo o tempo necessário para executar a operação de atualização de estatísticas, atualizando-se apenas a partição modificada.

O outro ponto importante é que a porcentagem de alterações de dados necessário para acionar a atualização automática de estatísticas, sendo este o valor 20% de linhas alteradas, o que proporcionará o uso de atualização de estatísticas no nível da partição, comportamento que não era permitido anteriormente.

Muito legal este novo recurso e principalmente o comportamento do Microsoft SQL Server, agora que já conhecemos conceitualmente como as estatísticas incrementais funcionam, chegou a hora de colocar as mãos no teclado e começar a conhecer de maneira prática esta funcionalidade.

Preparando o ambiente

Para entender a atualizar as estatísticas incrementais, vamos preparar um banco de dados de teste com uma tabela particionada. Começamos com a criação de um novo banco de dados denominado IncrementalStatistics, formado por quatro novos grupos de arquivos além de grupo de arquivos primário padrão, para tal vamos utilizar o Bloco de Código 1 apresentado a seguir:

— Bloco de Código 1 —

— Criando o Banco de Dados IncrementalStatistics —
Create Database IncrementalStatistics
Go
— Adicionando os Filegroups —
Alter Database IncrementalStatistics
Add Filegroup IncrementalStatisticsGrupo1
Go
Alter Database IncrementalStatistics
Add Filegroup IncrementalStatisticsGrupo2
Go
Alter Database IncrementalStatistics
Add Filegroup IncrementalStatisticsGrupo3
Go
Alter Database IncrementalStatistics
Add Filegroup IncrementalStatisticsGrupo4
Go

 

— Adicionando os Arquivos aos seus respectivos Filegroups —

Alter Database IncrementalStatistics
Add File (Name = N’IncrementalStatisticsGrupo1′,
FileName = N’S:\MSSQL-2016\Data\Arquivo-Grupo1-Data.ndf’,
Size = 4096KB,
FileGrowth =1024KB) To Filegroup IncrementalStatisticsGrupo1
Go

Alter Database IncrementalStatistics
Add File (Name = N’IncrementalStatisticsGrupo2′,
FileName = N’S:\MSSQL-2016\Data\Arquivo-Grupo2-Data.ndf’,
Size = 4096KB,
FileGrowth =1024KB) To Filegroup IncrementalStatisticsGrupo2
Go

Alter Database IncrementalStatistics
Add File (Name = N’IncrementalStatisticsGrupo3′,
FileName = N’S:\MSSQL-2016\Data\Arquivo-Grupo3-Data.ndf’,
Size = 4096KB,
FileGrowth =1024KB) To Filegroup IncrementalStatisticsGrupo3
Go

Alter Database IncrementalStatistics
Add File (Name = N’IncrementalStatisticsGrupo4′,
FileName = N’S:\MSSQL-2016\Data\Arquivo-Grupo4-Data.ndf’,
Size = 4096KB,
FileGrowth =1024KB) To Filegroup IncrementalStatisticsGrupo4
Go

Uma vez que o banco de dados é criado com os novos grupos de arquivos e arquivos de dados, precisamos prepará-lo para hospedar a tabela particionada. Nosso próximo passo consiste na criação da função particionada PartitionFunctionIncrementalStatistics que classifica os dados de acordo com os quatro trimestres do ano, sendo assim, vamos utilizar o Bloco de Código 2 apresentado abaixo:

— Bloco de Código 2 —

— Criando a Partition Function PartitionFunctionIncrementalStatistics —
USE IncrementalStatistics
GO

CREATE PARTITION FUNCTION PartitionFunctionIncrementalStatistics (Int)
AS
RANGE RIGHT FOR VALUES
(20171, 20172, 20173, 20174)
Go

Note que nossa PartitionFunctionIncrementalStatistics é composta por quatro partições de valores subdivididos da seguinte forma: 

  • 20171 – Valor que representa o Primeiro Quartil;
  • 20172 – Valor que representa o Segundo Quartil;
  • 20173 – Valor que representa o Terceiro Quartil do Ano; e
  • 20174 – Valor que representa o Quarto Quartil do Ano.

    Talvez você ainda não esteja entendendo o porque estamos fazendo uso deste tipo de implementação, tenha calma no decorrer do post tudo vai ficar mais claro e você terá total noção do porquê estamos utilizando este recurso.

Continuando com a nossa longa caminhada, você deve saber que para se trabalhar com particionamento de dados devemos além de criar uma Partition Function devemos obrigatoriamente criar um Partition Scheme,  que estará vinculado lógicamente a nossa partition function, sendo assim, este é nosso próximo passo, fazendo uso do Bloco de Código 3:

— Bloco de Código 3 —

— Criando o Partition Scheme PartitionSchemeIncrementalStatistics —
CREATE PARTITION SCHEME PartitionSchemeIncrementalStatistics AS
PARTITION PartitionFunctionIncrementalStatistics
TO
(
IncrementalStatisticsGrupo1,
IncrementalStatisticsGrupo2,
IncrementalStatisticsGrupo3,
IncrementalStatisticsGrupo4,
[PRIMARY])
Go

Esta quase tudo pronto para nossa brincadeira, seguiremos com a criação na nossa tabela TableIncrementalStatistics, este é um ponto importante do nosso ambiente, onde estamos fazendo uso da tabela particionada para ilustrar como as estatísticas incrementais vão realizar o seu papel.

TableIncrementalStatistics será composta por algumas colunas, dentre as quais a coluna Quartil, responsável em armazenar o valor do quartil de acordo com o ano informado, como também, é através desta coluna que estaremos realizando o particionamento dos dados. Para isso utilizaremos o Bloco de Código 4 a seguir:

— Bloco de Código 4 —

— Criando a Tabela TableIncrementalStatistics —

CREATE TABLE TableIncrementalStatistics
(ID Int Null,
Acao NVarchar(40) Default NewID(),
Data DateTime Null,
Quartil  AS (datepart(year,[Data])*(10)+datepart(quarter,[Data])) PERSISTED
) ON PartitionSchemeIncrementalStatistics (Quartil)
Go

Ótimo, toda estrutura para armazenar nossos dados já esta pronta, bem como, a lógica para distribuir e particionar os dados que serão inseridos na tabela TableIncrementalStatistics.

Ufa, ainda temos um bom caminho pela frente, mas já avançamos bastante, agora temos realizar uma alteração nas configurações do nosso banco de dados IncrementalStatistics, sendo esta necessária para podermos aplicara o uso de estatísticas incrementais, estou me referindo a opção Auto Create Statistics muito conhecida, onde vamos alterar o seu valor default para Incremental = On, conforme apresenta o Bloco de Código 5 abaixo:

— Bloco de Código 5 —

— Habilitando o uso de Incremental Statistics —
Alter Database IncrementalStatistics
Set Auto_Create_Statistics On (INCREMENTAL = On)
Go

O próximo passo consiste na criação do índice que iremos utilizar em na TableIncrementalStatistics pois você deve ter notado que realizamos a criação da tabela sem a definição de uma chave primária, desta maneira  utilizamos o Bloco de Código 6 para criação dos respectivo índice em seguida confirmamos se esta tabela esta fazendo uso das estatísticas incrementais habilitada no bloco de código 5:

— Bloco de Código 6 —

— Criação do índice Clustered —
Create Clustered Index Ind_TableIncrementalStatistics_ID
On [TableIncrementalStatistics] (ID)
GO

— Confirmando se as estatísticas incrementais está habilita —
SELECT
OBJECT_NAME(object_id) TableName
,name
,is_incremental
,stats_id
FROM sys.stats
WHERE name = ‘Ind_TableIncrementalStatistics_ID’
Go

Figura 1 – Confirmando o uso das estatísticas incrementais no índice Ind_TableIncrementalStatistics_ID.

Observação: Note que ao executar o Select realizado na visão de sistema sys.stats a coluna Is_Incremental deverá retornar e apresentar o valor igual á 1, isso indica que TableIncrementalStatistics esta neste momento fazendo uso das estatísticas incrementais.

Muito bem, chegou a hora de popular nossas tabelas, realizaremos a inserção de 8.000 linhas de registros, sendo estes particionados em grupos de 2.000 registros para cada partição que forma e compõem a estrutura da nossa tabela. Vamos então utilizar o Bloco de Código 7 apresentado na sequência:

— Bloco de Código 7 —

— Inserindo os dados na TableIncrementalStatistics —
Insert Into TableIncrementalStatistics (ID, Data)
Values (1, ‘2017-11-22’)
Go 2000

Insert Into TableIncrementalStatistics (ID, Data)
Values (2, ‘2017-06-05’)
Go 2000

Insert Into TableIncrementalStatistics (ID, Data)
Values (3, ‘2017-01-25’)
Go 2000

Insert Into TableIncrementalStatistics (ID, Data)
Values (4, ‘2017-08-13’)
Go 2000

Após a inserção das 8.000 linhas de registros, vamos confirmar a distribuição dos dados através do Bloco de Código 8 declarado abaixo, conforme ilustra o resultado da Figura 2:

— Bloco de Código 8 —

— Consultando a distribuição e particionamento dos dados —
Select partition_number, rows
From sys.partitions
Where OBJECT_NAME(OBJECT_ID)=’TableIncrementalStatistics’
Go

Figura 2 – Distribuição dos dados na tabela TableIncrementalStatistics de acordo com o valor e partição.

Estamos chegando no final, agora vamos realizar algumas manipulações no conjunto de dados armazenados na tabela TableIncrementalStatistics afim de forçarmos o processos de atualização das estatísticas, procedimento que vai nos ajudar a entender o processo de incremento na atualização das estatísticas de armazenamento e processamento utilizados pelo Microsoft SQL quando solicitado acesso aos dados armazenados em nossa table, para tal operação vamos utilizar o Bloco de Código 9:

— Bloco de Código 9 —

— Consultando dados na TableIncrementalStatistics —
Select Id, Acao, Data, Quartil From TableIncrementalStatistics
Where ID = 1
Go

Select Id, Acao, Data, Quartil From TableIncrementalStatistics
Where ID >= 2
Go

Select Id, Acao, Data, Quartil From TableIncrementalStatistics
Where ID <> 3
Go

Pronto, realizamos algumas operações de Select com intuito de forçar a criação de novas estatísticas, e principalmente a atualização das estatísticas atuais. Por enquanto nada de diferente, na sequência vamos consultar as informações sobre as estatísticas relacionadas a nossa tabela, fazendo uso do Bloco de Código 10 e analisando o resultado apresentado através da Figura 3:

— Bloco de Código 10 —

— Consultando as informações sobre as estatísticas da tabela TableIncrementalStatistics —
Select object_id, stats_id , last_updated , rows , rows_sampled , steps
From sys.dm_db_stats_properties(OBJECT_ID(‘[TableIncrementalStatistics]’),1);
Go

Figura 3 – Dados relacionados a estatísticas da TableIncrementalStatistics.

Como você pode ver, o DMF sys.dm_db_stats_properties mostra-nos que as estatísticas foram atualizadas na data do dia 23/05/2017 ás 16:55, para a tabela que tem 8000 linhas.

Neste momento, podemos nos perguntar: Qual partição da tabela inclui as estatísticas atualizadas?

A resposta para esta sua pergunta vem justamente atráves do uso nova DMF sys.dm_db_incremental_stats_properties já apresentada aqui no meu blog. Sendo esta DMF responsável em apresentar as propriedades estatísticas incremental, recuperando as mesma informação obtida a partir do DMF sys.dm_db_stats_properties, também super conhecida e apresentada no meu blog. Neste caso a sys.dm_db_stats_properties vai apresentar dados de  cada partição da tabela particionada, fornecendo-lhe com os mesmos parâmetros; a identificação do objeto e a identificação de estatísticas.

Caminhando mais um pouco, estamos próximos do final, vamos então formar o SQL Server a justamente realizar o processo de atualização das estatísticas para nossa partição de número 3, realizando o processo de exclusão de 1.500 linhas de registros, em seguida consultando nossa TableIncrementalStatistics, conforme apresenta o Bloco de Código 11:

— Bloco de Código 11 —

— Excluíndo 1.500 linhas —
Delete Top (1500) From TableIncrementalStatistics
Where ID = 2
Go

— Consultando os dados —
Select Id, Acao, Data, Quartil From TableIncrementalStatistics
Where ID <> 4
Go

Agora vamos novamente consultar os dados estatísticas, sendo assim repita a execução do Bloco de Código 10, observe que você deverá receber um conjunto de valores similares a Figura 4, onde a coluna Last_Updated deverá apresentar a data e hora da última atualização:

Figura 4 – Data e hora da última atualização da estatística.

Ufa, estamos quase lá, agora chegou a hora da verdade, hora de comprovar se realmente o SQL Server esta fazendo as coisas certas, vamos fazer uso da DMF sys.dm_incremental_stats_properties para validar se a estatística da partição 3 foi atualizada, o resultado pode ser analisado através da Figura 5. Para isso vamos utilizar o Bloco de Código 12 a seguir:

— Bloco de Código 12 —

— Consultando as informações sobre as estatísticas incrementais —
Select object_id, stats_id,
partition_number,
last_updated,
rows, rows_sampled,
steps
From sys.dm_db_incremental_stats_properties(OBJECT_ID(‘TableIncrementalStatistics’),1)
Go

Figura 5 – Informações sobre as atualizações de estatísticas, onde a partição 3 foi atualizada de maneira independente das demais.

Sensacional, conseguimos, muito legal este recurso, como sempre o Microsoft SQL Server nos surpreende com a sua capacidade e potencialidade de recursos.

Referências

Post Anteriores

https://pedrogalvaojunior.wordpress.com/2017/04/13/dica-do-mes-microsoft-sql-server-identificando-as-transacoes-que-estao-utilizando-o-transact-log/

https://pedrogalvaojunior.wordpress.com/2017/03/01/dica-do-mes-microsoft-sql-server-2016-sp1-novo-argumento-use-hint-disponivel-para-query-hints/

https://pedrogalvaojunior.wordpress.com/2017/01/16/dica-do-mes-conhecendo-a-nova-dmf-sys-dm_exec_input_buffer-no-microsoft-sql-server-2016/

https://pedrogalvaojunior.wordpress.com/2016/11/28/dica-do-mes-sql-server-2016-sp1-comando-create-or-alter/

https://pedrogalvaojunior.wordpress.com/2016/10/24/dica-do-mes-sql-server-2016-obtendo-informacoes-sobre-o-cache-de-execucao-de-funcoes/

Conclusão

Administrar, gerenciar, cuidar e prover um ambiente sempre no melhor estado possível não é uma das atividades mais tranquilas e simples desempenhadas por profissionais ou administradores de banco de dados, mas também não pode ser considerada um “bicho de sete cabeças” ou uma “caixa preta” ainda mais quando este servidor de banco de dados utiliza o Microsoft SQL Server.

Neste post você pode conhecer um pouco mais de como o Microsoft SQL Server trabalha de maneira árdua na busca da melhor maneira para encontrar e retornar os dados solicitados em nossas transações. Ao longo de novas versões o produto esta cada vez mais maduro, confiável e inteligente, sempre nos surpreendendo com sua capacidade.

Algo que não poderia ser diferente no uso das Estatísticas Incrementais, recurso que nos permite adotar uma nova maneira de atualização dos dados internos relacionados ao armazenamento das nossas informações, mas principalmente prover um auxílio para próprio Database Engine mas atividades para identificar o melhor caminho para se processar uma query.

Agradecimentos

Mais uma vez obrigado por sua visita, agradeço sua atenção, fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Um forte abraço, nos encontramos logo logo…

Valeu….

Dica do Mês – Microsoft SQL Server – Identificando as transações que estão utilizando o Transact Log


Bom dia pessoal, tudo bem?

Véspera de feriado religioso e um dos mais importantes para boa parte da população mundial! Justamente por ser véspera de feriado hoje é um daqueles dias que qualquer profissional da área de banco de dados reza para que nada ocorra de errado próximo ás 17hrs ou mais conhecido como 5 horas da tarde.

Pensando neste tipo de necessário o post de hoje dedicado a sessão Dica do Mês tem o objetivo de ajudar você profissional que esta em apuros neste momento tentando identificar o que pode estar ocorrendo em seu ambiente ou servidor Microsoft SQL Server.

Hoje vou apresentar como você pode no Microsoft SQL Server a partir da versão 2008 R2 identificar quais transações estão realizando o acesso e demandando informações para o Transact – Log, arquivo utilizado por qualquer banco de dados existente em seu servidor ou instância SQL Server para registrar dados relacionados as transações atuais ou já processadas, sendo este mais conhecido como log de transações.

Estão vamos em frente…..


Introdução

Quando se referimos ao log de transações, temos sempre aquele boa e velha definição, “o transact log é o arquivo utilizado pelo banco de dados para registrar o que esta sendo processado por nossas transações, conhecido como o dedo duro”, na verdade o transact-log é bem mais do que isso, trata-se de um dos principais componentes de qualquer banco de dados criado no Microsoft SQL Server que nos permite através do seu uso garantir a continuidade e disponibilidade de nossos dados para diversos cenários de armazenamento e principalmente recuperação de informações.

Durante o processamento de uma ou mais querys o transact-log pode apresentar comportamentos diversas de acordo com o que esta sendo processado, mas principalmente no que se relacionado aos processos de escrita e leitura do log, onde nossas querys podem gerar processos de gravação de dados no transact-log e internamente o SQL Server pode necessitar a acessar outros dados em log para atender outras possíveis demandas.

Estes processos são conhecidos como leitura ou escrita do transact-log, situações que podem impactar aleatoriamente no processamento de nossas querys.

Pensando neste tipo de possibilidade, o post de hoje visa ilustrar e apresentar como através do Management Studio ferramenta de administração e gerenciamento do Microsoft SQL Server podemos em conjunto com as DMVs – Dynamic Management Views listadas abaixo, monitorar, catalogar e identificar quais querys ou transações estão fazendo uso do Transact-Log em possíveis processos de leitura ou escrita do log.

Dynamic Management Views

Para saber mais sobre cada DMV acesse as referências apresentadas no final do post:

  • sys.dm_tran_session_transactions;
  • sys.dm_tran_active_transactions;
  • sys.dm_tran_database_transactions;
  • sys.dm_exec_sessions;
  • sys.dm_exec_requests; e
  • sys.dm_exec_sql_text.

O Cenário

Para tentar ilustrar como podemos realizar de maneira fácil este tipo de monitoramento e identificação, vamos criar um pequeno cenário através do Bloco de Código 1, onde estaremos realizando a criação de um novo banco de dados denominado UsingTransactLog para armazenar a tabela TabelaTransactionLog.

— Bloco de Código 1 —
— Criando o banco de dados —
Create Database UsingTransactLog
Go

— Acessando o banco de dados —
Use UsingTransactLog
Go
— Criando a tabela —
Create Table TabelaTransactLog
(TransactionID Int Default Current_Transaction_ID(),
TransactionUser Varchar(100) Default System_User,
TransactionDate DateTime Default Current_TimeStamp)
Go

 

Note que nosso tabela TabelaTransactLog possui um simples estrutura composto por três colunas: TransactionID, TransactionUser e TransactionDate, sendo estes elementos básicos utilizados para catalogar o ID da transação em processamento, o usuário conectado ao banco de dados e data/hora do momento da inserção da linha.

Até aqui nada de tão importante, mas importante para podemos simular o uso do log, nosso próximo passo consiste no processamento do Bloco de Código 2, onde estaremos realizando o processamento de uma transação de inserção de 50.000 mil linhas de registros, sendo a operação de insert uma das mais diversas operações que demando processos de escrita ao transact – log, sendo assim, apresento a seguir o Bloco de Código 2:

— Bloco de Código 2 —
Insert Into TabelaTransactLog Default Values
Go 50000

Observe que não estamos passando nenhum tipo de valores para nossas colunas, na verdade estou forçando o SQL Server a utilizar a criação de valores padrões durante o processamento de cada linha de registro através da instrução Default Values (valores padrões), o que vai obrigar nossa instância e ter que gerar valores durante o tempo de processamento e posteriormente registrar em log.

Muito bem, o processamento desta massa de dados, teremos a necessidade de abrir uma nova query para justamente fazer uso do Bloco de Código 3, sendo este o principalmente elemento do nosso cenário, a query que nos permiti monitorar e identificar as transações que estão em tempo real utilizando o transact-log. Então abra uma nova query e log o Bloco de Código 3 apresentado a seguir:

— Bloco de Código 3 —
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
Go

SELECT tst.session_id As ‘Sessão’,
es.original_login_name As ‘Login’,
DB_NAME(tdt.database_id) AS ‘Database’,
DATEDIFF(SECOND, tat.transaction_begin_time, GETDATE()) AS ‘Tempo decorrido’,
tdt.database_transaction_log_record_count AS ‘Espaço Utilizado’,
CASE tat.transaction_state
WHEN 0 THEN ‘A transação não foi completamente inicializada ainda…’
    WHEN 1 THEN ‘A transação foi inicializada, mas não começou…’
    WHEN 2 THEN ‘A transação esta ativa…’
    WHEN 3 THEN ‘A transação foi encerrada…’
    WHEN 4 THEN ‘Foi iniciado o processo de confirmação sobre o transação distribuída…’
    WHEN 5 THEN ‘A transação está em estado preparação e esperando resolução…’
    WHEN 6 THEN ‘A transação foi confirmada…’
    WHEN 7 THEN ‘A transação esta sendo revertida para o estado anterior…’
    WHEN 8 THEN ‘A transação foi revertida para o estado anterior…’
   ELSE ‘Estado da transação desconhecido’
   END AS ‘Estado da Transação’,
SUBSTRING(TXT.text, ( er.statement_start_offset / 2 ) + 1, ((CASE WHEN er.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), TXT.text)) * 2
ELSE er.statement_end_offset
END – er.statement_start_offset ) / 2 ) + 1) AS ‘Query Atual’,
TXT.text AS ‘Query relacionada’,
es.host_name As ‘Hostname’,
   CASE tat.transaction_type
    WHEN 1 THEN ‘Transação Read/Write’
    WHEN 2 THEN ‘Transação Read-Only’
    WHEN 3 THEN ‘Transação de Sistema’
                WHEN 4 THEN ‘Transação distribuída’
            ELSE ‘Tipo de Transação desconhecido’
            END AS ‘Tipo da Transação’,
tat.transaction_begin_time AS ‘Iniciado em’
FROM sys.dm_tran_session_transactions AS tst INNER JOIN sys.dm_tran_active_transactions AS tat
ON tst.transaction_id = tat.transaction_id
INNER JOIN sys.dm_tran_database_transactions AS tdt
ON tst.transaction_id = tdt.transaction_id
INNER JOIN sys.dm_exec_sessions es
ON tst.session_id = es.session_id
INNER JOIN sys.dm_exec_requests er
ON tst.session_id = er.session_id
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) TXT
ORDER BY [Tempo decorrido] DESC
Go
Pois bem, você pode estar querendo saber um pouco mais sobre o que exatamente esta acontecendo ao processar o Bloco de Código 3, pode ficar tranquilo que a seguir vou fazer um pequeno overview sobre este bloco de código, começando pelo conjunto de colunas retornadas por ele:
  • Sessão – Apresenta o ID da sessão que esta utilizando o transact-log;
  • Login – Nome da conta de login que esta conectada ao SQL Server;
  • Database – Nome do banco de dados utilizado pela query que esta acessando o transact-log;
  • Tempo decorrido – Representa o tempo de processamento que o query esta demandando para utilizar o transact-log;
  • Log Record Count– Identifica a quantidade de registros de log gerados pela query ou transações em processamento;
  • Estado da transação – Esta coluna apresenta o estado atual da query em processamento, sendo este formado por um conjunto de valores;
  • Query Atual – Apresenta as instruções que estão sendo processadas por cada query;
  • Query Relacionada– Apresenta as instruções processadas por querys que podem estar relacionadas com as atuais querys em processamento;
  • Hostname – Apresenta o nome dos hosts utilizados por cada query em processamento;
  • Tipo de Transação – Identifica se a transação em processamento esta realizando acesso de leitura ou escrita ao log, bem como, se esta query é uma query de sistema ou distribuída; e
  • Iniciado em – Apresenta o horário de início do acesso ao transact-log por parte da query em processamento.

Agora que você já conhece um pouco sobre cada coluna que será retornada após o processamento do Bloco de Código 3, vou abordar o uso da instrução Set Transaction Isolation Level declarada no início do código, que possui a finalidade de alterar no nível de isolamento do nosso banco de dados para Read Uncommitted afim de força o SQL Server a descartar ou desconsiderar qualquer possível ocorrência de bloqueios tanto no nível de tabela e registros, mas principalmente no escopo de banco de dados.

Nota: Se você me perguntar que isso é obrigatório ser feito para conseguir identificar as querys que estão utilizando o transact-log eu vou responder NÃO, isso não é obrigatório, mas pode ser considerada uma possível solução para garantir que o Bloco de Código 3 possa ser processado e consultar as dynamic management views na busca das informações catalogadas por ela em tempo de execução.

Ufa, estamos quase lá, agora nos resta fazer a execução do mesmo e observar o retorno dos dados coletados por este bloco de código, com base, na Figura 1 apresentada abaixo:

Figura 1 – Relação de querys em execução utilizando transact-log.

Perfeito, nosso monitoramento funcionou, conseguimos coletar os dados referentes as querys que estão neste momento em processamento fazendo acesso e utilizando o transact-log criado para o banco de dados UsingTransactLog.

Isso não é sensacional, desta forma, chegamos ao final de mais um post dedicado a sessão Dica do Mês, espero que você tenha gostado.

Referências

Post anteriores

  1. https://pedrogalvaojunior.wordpress.com/2017/03/01/dica-do-mes-microsoft-sql-server-2016-sp1-novo-argumento-use-hint-disponivel-para-query-hints/
  2. https://pedrogalvaojunior.wordpress.com/2017/01/16/dica-do-mes-conhecendo-a-nova-dmf-sys-dm_exec_input_buffer-no-microsoft-sql-server-2016/

  3. https://pedrogalvaojunior.wordpress.com/2016/11/28/dica-do-mes-sql-server-2016-sp1-comando-create-or-alter/

  4. https://pedrogalvaojunior.wordpress.com/2016/10/24/dica-do-mes-sql-server-2016-obtendo-informacoes-sobre-o-cache-de-execucao-de-funcoes/

Conclusão

Administrar, gerenciar, cuidar e prover um ambiente sempre no melhor estado possível não é uma das atividades mais tranquilas e simples desempenhadas por profissionais ou administradores de banco de dados, mas também não pode ser considerada um “bicho de sete cabeças” ou uma “caixa preta” ainda mais quando este servidor de banco de dados utiliza o Microsoft SQL Server.

Neste post você pode observar que através do uso de alguns DMVs – Dynamic Management Views a Microsoft nos permite coletar, analisar e entender de forma visual e muito intuitiva como o um servidor ou instância SQL Server gerencia o que esta sendo processado por nossas aplicações, querys ou transações no que se relaciona aos seus componentes e recursos internas, algo que nos permite em diversas situações de administração ou manutenção tentar identificar o que pode estar ocorrendo, bem como, impactando em nosso ambiente.

Agradecimentos

Mais uma vez obrigado por sua visita, agradeço sua atenção, fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Um forte abraço, bom feriado, espero que neste momento você não esteja no seu trabalho tentando resolver problemas do seu servidor (kkkkk).

Valeu….

Dica do Mês – Microsoft SQL Server 2016 SP1 – Novo argumento USE HINT disponível para Query Hints


Boa tarde minha comunidade, salve, salve meu mestre SQL e porta bandeira Server……

É isso pessoal, quarta – feira de cinzas para muitos no brasil, mas graças a deus deste mal ou depressão eu não vou morrer, estou retornando em mais um post da sessão Dica do Mês, e se por acaso você não tem acessado o meu blog nos últimos meses não tem problema, uso um dos links abaixo para acessar as três últimos dicas do mês publicadas:

1.      https://pedrogalvaojunior.wordpress.com/2017/01/16/dica-do-mes-conhecendo-a-nova-dmf-sys-dm_exec_input_buffer-no-microsoft-sql-server-2016/

2.      https://pedrogalvaojunior.wordpress.com/2016/11/28/dica-do-mes-sql-server-2016-sp1-comando-create-or-alter/

3.      https://pedrogalvaojunior.wordpress.com/2016/10/24/dica-do-mes-sql-server-2016-obtendo-informacoes-sobre-o-cache-de-execucao-de-funcoes/

Hoje vou destacar mais uma melhoria adicionada recentemente ao Microsoft SQL Server 2016 a partir da instalação do Service Pack 1, sendo este sem dúvida nenhuma o maior conjunto de melhorias e inovações já adicionadas ao SQL Server desde suas primeiras versões.

Caso você ainda não fez download deste service pack, não perca tempo, acesse o link abaixo e realize o download o quanto antes: https://pedrogalvaojunior.wordpress.com/2016/11/19/microsoft-disponibiliza-service-pack-1-para-o-microsoft-sql-server-2016/

Dando continuidade, hoje vou apresentar o novo Query Hint adicionado após a instalação do SP1 chamado de USE HINT, quando encontrei informações sobre este novo recursos acabei ficando um pouco confuso e sem entender em qual momento ele poderia ser útil, mas após um busca mais detalhada pude ter a certeza que valia a pena compartilhar um pouco sobre esta novidade com vocês.

Se você ainda não ouvir falar sobre uso de query hints ou dicas de consulta existentes no SQL Server, isso assunto não é nada novo muito pelo contrário trata-se de uma das práticas mais comuns utilizadas por profissionais de bancos de dados e desenvolvedores com objetivo de otimizar a execução de uma ou mais transações.

Agora no SP1 do 2016 o time de engenheiros do SQL Server adicionou este novo argumento que nos permite dentre suas finalidades fazer uso de alguns dos mais específicos query hints sem exigir elevação no nível de permissão, declaração de trace flags ou até mesmo que o usuário que esteja fazendo uso deste hint pertença ao server role sysadmin.

Bom se você quiser saber um pouco mais sobre este novo argumento, continue lendo este post….


Introdução

Cenários no qual SQL Server deve ser sugerido mudança de comportamento para o query optimizer são bastante comuns de serem encontrados, tradicionalmente o uso de query hints apresentam um papel fundamental neste contexto independente de qual sinalizador você esteja utilizando, sendo este reconhecido como um documentado ou não-documentados.

Entretanto, quando estes sinalizadores de rastreamento são definidos globalmente, eles podem ter um efeito adverso sobre outras cargas de trabalho. Além disso, o uso por sessão não é prático com aplicativos, bem como, por consulta com QUERYTRACEON, sendo que esta opção requer associação na função de servidor fixa sysadmin. Embora você pode contornar esse comportamento usando um guia de plano ou um procedimento armazenado, credenciais elevadas são ainda necessárias.

Estes sinalizadores de rastreamento são conhecidos como trace flags,  usados para configurar temporariamente características de servidor específico ou para desligar um determinado comportamento, podem ser difíceis de gerenciar e compreender sua forma de uso ou impactos.

A partir do Microsoft SQL Server 2016 SP1 temos a capacidade de fazer uso do novo query hint argument USE HINT diretamente em nossas querys ou transações de forma simples, rápida e segura, contornando qualquer necessidade de elevação permissional ou mudança no contexto de execução.

Dentre os diversos query hints existentes no SQL Server, o USE HINT nos permite fazer uso dos seguintes:

Opção Sinalizador de rastreamento equivalente Descrição
FORCE_LEGACY_CARDINALITY_ESTIMATION TF 9481 Permite que você defina o modelo de estimativa de cardinalidade do otimizador de consulta para o SQL Server 2012 e versões anteriores, independentemente do nível de compatibilidade do banco de dados.
ENABLE_QUERY_OPTIMIZER_HOTFIXES TF 4199 Controles de consulta alterações otimizador lançadas em Service Packs e atualizações cumulativas do SQL Server.
DISABLE_PARAMETER_SNIFFING TF 4136 Desabilita o parâmetro de rastreamento, a menos que o valor OPTION(RECOMPILE), WITH RECOMPILE ou OPTIMIZE FOR seja usado.
ASSUME_MIN_SELECTIVITY_FOR_FILTER_ESTIMATES TF 4137 Faz com que o SQL Server gere um plano usando seletividade mínima ao estimar e predicados para filtros de correlação, em modelo de estimativa de cardinalidade de consulta otimizador do SQL Server 2012 e versões anteriores.
DISABLE_OPTIMIZER_ROWGOAL TF 4138 Faz com que o SQL Server gere um plano que não usa ajustes de meta de linha com consultas que contenham as palavras-chave TOP, OPTION (FAST N), IN ou EXISTS.
ENABLE_HIST_AMENDMENT_FOR_ASC_KEYS TF 4139 Ativar automaticamente gerado estatísticas rápidas (emenda do histograma), independentemente do status da coluna de chave. Se essa opção for usada, independentemente do status de coluna estatísticas principais (em ordem crescente, decrescente ou papel de carta), o histograma usado para estimar a cardinalidade será ajustado em tempo de compilação de consulta.
ASSUME_JOIN_PREDICATE_DEPENDS_ON_FILTERS TF 9476 Faz com que o SQL Server gerar um plano usando a suposição de confinamento simples em vez da suposição de confinamento de Base padrão, no query optimizer cardinalidade estimativa modelo do SQL Server 2014 através de versões do SQL Server 2016.
DISABLE_OPTIMIZED_NESTED_LOOP TF 2340 Faz com que o SQL Server não use uma operação de classificação (classificação em lotes) para associações de loop aninhado otimizado ao gerar um plano.
FORCE_DEFAULT_CARDINALITY_ESTIMATION TF 2312 Permite que você definir o modelo de estimativa de cardinalidade de Otimizador de consulta para o SQL Server de 2014 por meio de versões do SQL Server 2016, dependentes do nível de compatibilidade do banco de dados.

Para consultar esta relação de hint options disponíveis para uso com USE HINT, a Microsoft adicionou um nova DMV denominada: sys.dm_exec_valid_use_hints, sendo esta melhor detalhada no próximo post da sessão Para que serve (não deixe de conferir). A seguir destaco algumas formas de uso do novo USE HINT em conjunto com alguns hints options.

Exemplos

Para ilustrar e ajudar a entender melhor os exemplos a seguir, utilize o banco de Dados AdventureWorksDWCTP3 disponível para download através do link: https://www.microsoft.com/en-us/download/details.aspx?id=49502

— Exemplo 1 – Utilizando o hint option FORCE_LEGACY_CARDINALITY_ESTIMATION —

usehint

— Exemplo 2 – Utilizando o hint option FORCE_LEGACY_CARDINALITY_ESTIMATION em conjunto com a QUERYTRACEON 9481 —

usehint2

Dica: Para que você possa entender e analisar melhor como o SQL Server 2016 se comportar a partir do momento que o argumento USE HINT é declarado, recomendo que você habilite a apresentação do recurso de Include Actual Execution Plan em seu Management Studio e execute estes exemplos sem a declaração do USE HINT e posteriormente com a declaração do mesmo, além disso, também realize a comparação dos planos de execução para notar e identificar as mudanças comportamentais.

Referências

·         https://msdn.microsoft.com/en-us/library/ms188396.aspx

·         https://support.microsoft.com/en-us/help/3189813/update-introduces-use-hint-query-hint-argument-in-sql-server-2016

·         https://msdn.microsoft.com/en-us/library/ms181714.aspx

·         https://msdn.microsoft.com/en-us/library/mt791356.aspx

·         https://blogs.msdn.microsoft.com/sql_server_team/developers-choice-use-hint-query-hints/

Conclusão

Como de costume a cada nova versão ou atualização a Microsft esta apresentando diversas inovações e melhorias no Microsoft SQL Server, mantendo o produto no seu mais alto nível de funcionalidades, recursos e inovações.

Neste post você pode perceber mais uma melhoria adicionada ao produto, onde através deste novo query hint USE HINT temos a capacidade de usar dicas de consulta orientando o query optimizer a mudar sua forma de execução e comportamento sem necessitarmos de elevação no nível de permissão ou fazermos partes de uma função de servidor sysadmin, algo que representa uma grande evolução por parte do produto no que se relacionado a controle de permissões e níveis de segurança.

Sinceramente eu vejo este novo recurso como um pequeno easter egg, pois na minha humilde opinião estava muito mas muito bem escondido.

Agradecimentos

Mais uma vez obrigado por sua visita, agradeço sua atenção, fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Valeu….

Dica do Mês – Conhecendo a nova DMF sys.dm_exec_input_buffer no Microsoft SQL Server 2016


Bom dia, bom dia, bom dia….. Feliz 2017

Salve, salve comunidade, estou retorno hoje, conforme o prometido após alguns dias de “descanso mental”. Espero que todos tenham passado um ótimo fim de ano e estejam preparados para os desafios de 2017.

Estamos completando o primeiro ano da sessão Dica do Mês, sendo este o post de número 12, poxa vida muito legal ver o quanto de conteúdo e conhecimento já foi transmitido nesta sessão.

Hoje dia 16 de Janeiro primeiro post de 2017 dedicado mais uma vez ao Microsoft SQL Server, dentre os quais voltados exclusivamente a versão 2016, vou destacar um assunto bem conhecido de qualquer DBA denominado Input Buffer.

Não vou destacar do que se trata este conceito mais sim apresentar como a partir do SQL Server 2016 podemos recurperar e coletar as informações relacionado a ele de uma maneira diferente se comparado com as versões anteriores.

Então vamos lá, seja bem vindo ao Dica do Mês número 12……

Introdução

Reconhecer e identificar o que esta sendo transacionado dentro do seu servidor ou instância do Microsoft SQL Server para muitos é coisa de outro mundo, para outros coletar estes dados não passa de um simples comando que você pode executar.

Na verdade os lados da moeda tem a sua verdade, identificar e entender o que esta sendo transacionado não é uma tarefa fácil por isso pode ser considerado algo fora da terra, como também, coletar e armazenar é algo muito simples, e realmente é!!!

Desde as versões mais antigas do SQL Server a maneira mais comum e menos consumista de se obter informações sobre o Buffer ou Input Buffer dentro de um servidor ou instância era através do comando DBCC Input Buffer, onde bastava simplesmente executar este comando para se obter a informações sobre o buffer de uma sessão específica.

Agora na versão 2016 desta RC0 a Microsoft de um novo jeitinho para se obter estes dados através do uso da nova DMF – Dynamic Management Function ou Função de Gerenciamento Dinâmico chamada Sys.dm_exec_input_buffer.

Ao executar pela primeira vez esta DMF, pensei que seria um recurso substituto ao bem e velho DBCC Input Buffer, ao começar a brincar um pouco mais com ela  observei que existe uma pequena similaridade entre ambos.

Similaridade que se tornou mais clara na maneira que a sys.dm_exec_input_buffer apresentar os dados coletados que estão sendo transacionados, o que também acabou ficando somente nisso, durante as diversas execuções que realizei, foi possível  reconhecer algumas pequenas diferenças que podemos reconhecer como vantagens no uso da sys.dm_exec_input_buffer em comparação ao DBCC InputBuffer.

Sys.dm_exec_input_buffer x DBCC Input Buffer

Basicamente a forma de uso de ambos os recursos não posso dizer que seja algo muito diferente, o DBCC InputBuffer você executa de forma direta passando o SID da sessão a qual você deseja obter o buffer, já a sys.dm_exec_input_buffer o mínimo a favor é executar um comando Select direcionado para esta DMF.

Falando das vantagens destaco abaixo as mais fáceis de se identificar:

  1. Ao executar a dmf o resultado é apresentado diretamente como um conjunto de linhas, o que permite em uma bloco de código obter os input buffers de diversas sessões, uma grande vantagem se comparada com o DBCC Input Buffer;
  2. Outra diferença clara é a capacidade de realizar joins com outras DMFs dentre elas: sys.dm_exec_sessions, sys.dm_exec_connections e sys.dm_exec_requests através do uso do operador Cross Join;
  3. Através da execução de uma simples query através do comando select podemos recuperar o buffer de diversas entradas de sessões distintas sem a necessidade de criar um script, tabela temporária ou tabela auxiliar; e
  4. Possibilidade armazenar o resultado da relação de buffers coletados em uma nova tabela.

Exemplos

Como já mencionei anteriormente a forma de uso da sys.dm_exec_input_buffer é bem simples e fácil, como também, a apresentação dos dados coletados, os dois exemplos apresentados a seguir demonstram como podemos fazer uso desta nova DMF no Microsoft SQL Server 2016:

— 1 – Executando um simples Select —
SELECT * FROM sys.dm_exec_input_buffer(52, 0);

dica-12-01Figura 1 – Buffer coletado da sessão 52.

— 2 – Utilizando o operador Cross Apply —
SELECT es.session_id, ib.event_info
FROM sys.dm_exec_sessions AS es
CROSS APPLY sys.dm_exec_input_buffer(es.session_id, NULL) AS ib
WHERE es.session_id > 50;

dica-12-02Figura 2 – Buffers coletados após a execução do exemplo 2.

Referências

Conclusão

Como de costume a cada nova versão ou atualização a Microsft esta apresentando diversas inovações e melhorias no Microsoft SQL Server, mantendo o produto no seu mais alto nível de funcionalidades, recursos e inovações.

Neste post você pode perceber que mais uma vez isso esta presente, uma nova maneira de se obter informações sobre os buffers que estão sendo transacionados e processados dentro de um servidor ou instância do SQL Server através da DMF sys.dm_exec_input_buffers.

Agradecimentos

Mais uma vez obrigado por sua visita, agradeço sua atenção, fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Conto com a sua presença em mais este ano aqui no meu blog….

Feliz 2017!!!

Dica do Mês – SQL Server 2016 SP1 – Comando Create Or Alter


Muito bom dia…..

Olá pessoal, mais uma semana começando. Estou retornando com mais um post dedicado a sessão Dica do Mês, este é o post de número 11 dedicado de forma exclusiva a esta sessão.

Como você já deve ter observado desde o mês de outubro todos os posts das sessões: Dicas do Mês, Para que Serve, Short Scripts e Material de Apoio estão apresentado o mesmo layout, sendo esta uma das sugestões que os meus seguidores solicitaram, e hoje não será diferente.

A dica de hoje é bastante simples e esta totalmente relacionada a uma novidade apresentanda com o lançamento do Service Pack 1 do Microsoft SQL Server 2016.

E ai você já esta se informando sobre este novo service pack? Já realizou o download? Posso lhe dizer que diversas melhorias foram implementas, bem como, muitas mas muitas mudanças identificadas pela equipe de desenvolvimento da Microsoft foram realizadas.

Se quiser saber mais sobre este novo conjunto de atualizações e melhorias dedicadas para o Microsoft SQL Server 2016, acesses os links abaixo:

 

Voltando ao post de hoje, vamos em frente, seja bem vindo a mais um Dica do Mês!!!


Introdução

A cada nova versão do Microsoft SQL Server que a Microsoft libera ou até mesmo após um service pack ou cummulative pack disponibilizados para download, sempre fazemos aquelas perguntas:

  • O que será que melhorou?
  • Quais correções foram definitivamente corrigidas?
  • Será que alguma solicitação do Connection foram atendidas?

Enfim sempre estamos querendo descobrir o que realmente o tipo de engenheiros e desenvolvedores voltados para o SQL Server estão pensando em melhorar e corrigir no produto.

Para esta versão não foi diferente como de costume desde a versão 2012 a Microsoft esta liberando em doses homeopáticas pequenas novidades voltadas para a linguagem Transact-SQL e isso se manteve no SP1 da versão 2016 com a introdução do comando Create or Alter na mesma instrução.

Isso mesmo você pode estar se perguntando ou até mesmo pensando, mas somente agora na versão 2016 este tipo de instrução foi adicionada? A resposta é sim, somente agora pois, algo que para muitos parecia ser simples se comparado com outras ferramentas de banco de dados como Oracle ou MySQL, mas como diz aquele velho ditado: “Nem tudo o que parece é” e isso também se justifica ao Microsoft SQL Server.

Problema

Você saberia me dizer quantas vezes teve que realizar a criação de um recurso programável em um servidor ou instância SQL Server? Algo do tipo Stored Procedure, Function, Trigger ou Views?

E realizar uma ou várias alterações na estrutura de codificação de algum tipo destes recursos? Com certeza é algo bastante comum de ser realizado principalmente quando estamos criando nossos ambientes.

Por muitos anos este tipo de atividade a ser realizada na linguagem Transact-SQL deveria ser feita de forma separada. Onde devemos basicamente seguir uma regra de criar um destes tipos de objetos através do comando Create e caso tenhamos a necessidade de realizar algum tipo de alteração utilizar o comando Alter.

Então, e se agora com o lançamento do service pack 1 para o SQL Server 2016 eu te dizer que isso já pode ser realizado de uma única vez, você acredita?

Eu posso te dizer que acredito pois é verdade…..

Solução

Dizer que demorou um pouco para a equipe de desenvolvimento entender o quanto esta melhoria seria útil e importante não é verdade, ao meu ver demorou bastante, eu posso dizer isso pois trabalho com SQL Server desde a versão 7, isso já se vão 18 anos.

Mas enfim dizer do passado muitas vezes não ajuda em nada, o que vale e deve ser destacado é que agora temos esta pequena mas importante melhoria implementada no Microsoft SQL Server 2016 SP1 que nos permite ao mesmo tempo que declaramos o comando Create adicionar na mesma linha o comando Alter, mas a princípio somente para os objetos programáveis dentre eles:

  • Function;
  • Stored Procedure;
  • Triggers; e
  • Views.

O Create or Alter voltado para tabelas ainda não esta presente neste momento, e sinceramente falando acredito que vai demorar mais um pouco para ser adicionado ao produto.

Legal, mesmo assim já tivemos um grande avanço com a liberação deste nova capacidade adicionada a linguagem Transact-SQL.

Exemplos

Pois bem, seguindo em frente e dando seta para direita afim de realizar uma ultrapassagem na atual versão do SQL Server 2016 mudando para nova versão SQL Server 2016 SP1 ou se preferir versão 13.0.4001 número que identifica e evolução do kernel para o SP1.

Acelarando um pouco mais, vamos trabalhar com alguns exemplos de código que ilustram como podemos fazer uso do comando Create or Alter, para tal torna-se necessário realizar o download do SP1, caso você ainda não tenha feito, utilize o link apresentado a seguir:

Dando continuidade vamos executar o primeiro bloco de código, denominado Bloco de Código 1 apresentado abaixo:

— Bloco de Código 1 —

create-alter-procedure-1
Podemos observar que a forma de uso desta instrução é bastante simples, não necessitando de algum tipo de alteração na sintaxe tanto do comando Create como também do Alter.

Observe que realizamos a criação de um simples Stored Procedure denonimado P_Teste e após a execução do create/alter realizar a apresentação do código fonte da mesma através do system stored procedure SP_HelpText.

Um detalhe importante que vale a pena ser destacado, se relacionado a apresentação do código fonte da nosso stored procedure, note que o SQL Server não adiciona a palava chave Alter na apresentação do código, você pode pensar, mas é claro nós acabamos de criar o objeto. Eu também pensei assim, mas isso não altera caso você realize qualquer tipo de alteração no código fonte, mesmo após realizar alguma mudança na codificação do seu objeto o Database Engine não reconhece a execução do comando Alter ele mais uma vez adiciona o comando ou palavra chave create antes do nome do objeto.

Isso me faz pensar que todas as vezes que utilizarmos este tipo de implementação o Database Engine vai na verdade realizar o processo de drop físico do objeto e posteriormente a criação deste objeto.

Vamos agora trabalhar da mesma forma para criação/alteração de uma function, para isso vamos utilizar o Bloco de código 2 apresentado a seguir:

— Bloco de Código 2 —

create-alter-function-1

Legal, legal, muito bem, simples, fácil, rápido e por quê não dizer que é prático! Ao mesmo tempo que criamos um objeto programável já podemos realizar a alteração. Isso não é algo que realmente estava faltando para o SQL Server?

Acredito que sim, e fazendo um comparativo era a mesma coisa que faltava quando se referiamos a existência de tipos de dados para armazenar somente data ou hora, algo que também foi implementada após um longo tempo a partir da versão 2008 do SQL Server, ou os comandos IIF ou Choice que já existiam na linguagem C#, mas não estavam presentes no Microsoft SQL Server até a versão 2012.

Bom vou deixar para que praticar o uso deste comando na criação de Triggers e Views, com certeza não terá problemas.

Referências

Conclusão

Como de costume a cada nova versão ou atualização a Microsft esta apresentando diversas inovações e melhorias no Microsoft SQL Server.

Desta forma, em um novo service pack lançado novas melhorias ou mudanças de comportamento do produto são esperadas, algo que a partir do service pack o SQL Server 2016 também vai apresentar.

O que a partir do momento que este conjunto de melhorias for instalada em seu ambiente, será possível dentre elas fazer uso da nova sintaxe combinado dos comandos Create e Alter utilizados de maneira simultânea formando o Create or Alter.

Agradecimentos

Mais uma vez obrigado por sua visita, agradeço sua atenção, fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Até mais.