Etiket Bulutu

Benchmark Convert_IMplicit Database High Availability Database Mirroring datawarehouse dimension table dmv Dynamic Data Masking Execution Execution Plans fact table Failover Cluster Node ekleme Failover Clustering FileStream generate script High Availability Implicit Instant File Initialization index Kinect Linux Live Query Statistics Log Shipping Mirroring object explorer object explorer details ODBC Driver pass performance performance tuning Plan Handle Planü Power View reporting services rol Row Level Security script sql serer 2016 sql server SQL Server 2008 SQL Server 2008 Log Shipping SQL Server 2012 SQL Server 2012 installation SQL Server 2012 Kurulumu SQL Server Backup SQL Server da Backup planı SQL Server da Maintenance Plans oluşturma SQL Server database mirroring SQL Server Disaster Recovery sql server dynamic management views SQL Server Failover Cluster SQL Server High Availability SQL Server Log Shipping SQL Server Maintenace Plans sql server performans SQLDIAG SQLDIAG Troubleshooting T24 Temenos truncate table t-sql unique index performance 1. Dünya savaşı istatistikleri 1456 451 ACID advanced analytics Advanced Data Analytics Affinity algı Alter index Alter table ALTER TABLE .. ALTER COLUMN Altın Oran Always On ALWAYSON AlwaysOnDemoTool amazon web services kinesis AMR analiz analysis service Ankara Antivirus apache kafka Arduino Article Assembly asymmetric audit Authentication Auto Growth Availability Group azure Azure Backup azure event hub partition azure event hubs azure event hubs servisi azure event hubs veri edinme Azure File Share Azure Fiyatlandırma Azure HDInsight Azure Hizmet Modelleri Azure ML Azure New Portal Azure Pricing Azure Queue azure sql database configuration azure sql database kullanımı azure sql database stream veriyi tutma azure sql database table partitioning Azure Storage azure stream analytics azure stream analytics dashboard azure stream analytics ölçeklendirilmesi azure stream analytics servisi Azure Table BA Backup backup encyrption backupset Bakım BASE bellek Best Practice BI Semantic Model Big Data Big User blocking blocking disable trigger blocking enable trigger Buffer Cache buffer pool Buffer Pool Extension bulk logged Buluta Veri Depolama Buluttaki Disk Business Analytics Conference business intelligence Büyük Veri Case Central Management Server certificate changed data capture Cloud Computing Cloud DR CLR Cluster clustered columnstore index Clustered Index Code Snippets Cold Purging collation column store column-level columnstore ColumnStore Indexes Compress ComputerNamePhysicalNetBIOS Concurrency Conditions Contained Database Contained Databases convert CONVERT_IMPLICIT Corruption Credentials cube DAC Dashboard Tasarımı data cleansing Data Compression Data Consistency Model data encryption data matching data mining Data Page data profiling data quality Data Services Data Warehouse Design Database database list Database Management Sistem database master key Database Mirroring Database Snapshot database trigger database-level Data-Ink Ratio datasets datasource DataZen date date dimension db_owner DBA DBCC dbcc dropcleanbuffers dbcc freeproccache DBMS dbo user DDL deadlock debugging DecryptByKey DecryptByPassPhrase deleted bitmap delta store Denali Denali SSAS deny database list deşifre detail index developer DIFFERENTIAL BACKUP DirectQuery Dirty Read Disaster Recovery Distribution Yapılandırma Distributor Distributor Agent dm_server_services DMF DMO DMV document db dosya bazlı şifreleme dqs dr Dynamic Management Function Dynamic Management Object Dynamic Management View ecrypt Effected Report Design Techniques Eğitim EncryptByKey EncryptByPassPhrase encryption endpoint Environment Variable error Error 5030 Error Log Estetik Raporlama Estimated Rows Eş Zamanlılkk Etkili Rapor Tasarlama Teknikleri Etkinlik ETL event Event Viewer except;intersect;sql execution Execution Plan export formats extended events Extended Stored Procedure Facets Failover Failover Cluster fast n execution plan FETCH NEXT FILELISTONLY FILLFACTOR File Table file-level FileStream Filter Pack Filtered Index First_Value Flat File fn_repl_hash_binary Focal Point foreignkey FORMAT Forwarded Record forwarded_record_count ftp task FULL BACKUP Full Recovery Full-Text Search functions Gartner Geocluster Gerçek Zamanlı Dashboard gestalt Golden Ratio görsel duyu group by Güvenlik ha Hadoop hafıza Hash HASHBYTES HEADERONLY headers footers Heap Hekaton hicri High Availability hijr Hiyerarşi Hybrid Cloud IaaS Index Index Scan In-Memory InMemory DW In-Memory DW InMemory OLTP In-Memory OLTP Internet of People Internet of Things IO IOT IoT nedir Isolation Level indeks index inmemory in-memory oltp internet of things isolation level istatistik istatistikler İş zekası İzolasyon Seviyesi Job json json support knowledge base kolon-satır bazlı kurulum küp Lag Lansman latch Lead linked server lock locking locking hints Log Backup Log Reader Agent Log Shipping login Lost-Update LQS Machine Learning Maintenance Management Studio matrix Max Text Replication Size mdx memory Memory Optimization Advisor Memory Optimized Table Memory Optimized Tables merge Merge Agent merge kullanımı Merge Publication Merge Replication merge type 1 slowly changing dimension merge type 1 slowly changing dimension örneği merge type 1 vs type 2 scd merge type 2 slowly changing dimension merge type 2 slowly changing dimension örneği merge type 3 slowly changing dimension merge type 4 slowly changing dimension message Microsoft Advanced Data Analytics Çözümleri microsoft azure Microsoft Bulut Microsoft Sanal Akademi Microsoft SQL Server Microsoft SQL Server 2014 Yenilikleri Microsoft SQL Server 2016 Mirror mirroring missing index Monitoring move Msdb multi_user multiversion concurrency control MVP MVP Roadshow MySnippet Named Pipes Natively Store Procedures Natively Stored Procedures Nesnelerin İnterneti Network Binding Order NoEngine Approaches nonclustered columnstore index Non-Repetable Read NoSQL NoSQL Approaches NoSQL Dünyası object explorer Odak Noktası ODBC Office 365 Offline OFFSET olap OLAP Backup OLE DB OLTP Online Index order attributes Otomatik Büyüme OVER PaaS PAD_INDEX page out page properties PAGE RESTORE PAGEIOLATCH paging parameters partition partitioning PASS PASS Summit PASS Summit 2014 Performance Performance Tuning performans performans tuning Phantom Read pivot Policies Policy Based Management Filtreleme Policy Management Power BI Power BI Dashboard Power BI Rest API power bi power view PowerBI PowerBI for Office 365 powerbi PowerMap PowerPivot PowerQuery powershell powershell ile sql yönetimi PowerView PowerView raporlarının web sayfalarına gömülmesi precon Primary Key primarykey Project Deployment Model Project Variable Protokol Proxy Proxy Account Publisher Purging on Independent Tables QL Server 2014 Yenilikleri Que Reader Agent Query Plan query store R Range Raporlama Raporlama Projeleri için Strateji Belirleme Raporlama Projelerine Hazırlık Read Committed Read Uncommitted RealTime Dashboard Rebuild RECONFIGURE RECONFIGURE WITH OVERRIDE Recovery model Relational Engine relationships Rename SSRS Database Repeatable Read Replication Replication Monitoring replikasyon report manager web site report parts reporting service reporting services reporting servis Resource Governor RESTORE Restore Database Restore Generate Restore Generate Script Restore transaction log rollback rs Rule of Thirds sa user SaaS sayfalama scd 3 demo scd karşılaştırma scd type 4 demo Scheduling Schema Comparison script Security segment elimination select into Self-Service BI Semantic Search Serializable Server Core SERVERPROPERTY Service services shared data sources shared datasets Shared Memory sharepoint Sharepoint 2010 ShowPlan Shrink simple recovery sing_user sliding window Slowly Changing Dimension snapshot Snapshot Agent Snapshot Publication Snapshot Replication Snippet snowflake sorting sp_configure sp_describe_first_result_set sp_server_diagnostics sp_spaceused sql SQL Agent Job SQL Azure sql bilgi yarışması SQL CLR SQL DIAG SQL DIAG Performans verisi toplama SQL endpoint SQL Login SQL Onculeri SQL Öncüleri sql script sql server SQL Server 2005 SQL Server 2008 SQL Server 2011 CTP3 SQL Server 2011 Denali SQL Server 2012 SQL Server 2012 CTP3 SQL Server 2012 RC SQL Server 2012 RC0 SQL Server 2012 ShowPlan Enhancements SQL Server 2012 T-SQL Enhancements SQL Server 2014 Sql Server 2014 Cardinality Estimator SQL Server 2014 Yenilikleri sql server 2016 SQL Server 2016 New Features SQL Server 2016 Yenilikleri sql server agent sql server assembly ekleme SQL Server Authentication sql server cast ve convert sql server clr integration sql server clr kullanımı sql server clr örnek sql server cluster SQL Server Code Name Denali SQL Server da Kullanıcı Yaratma SQL Server Database Project sql server dmv ve dmf sql server execution plan temizleme SQL Server Express Backup sql server fast n option örneği sql server fast n seçeneği SQL Server login sql server management stdio sql server merge into örnek sql server merge komutu sql server merge performnas sql server merge type 1 scd sql server merge type 2 scd sql server merge type 3 scd SQL Server Mobile Report Publisher SQL Server Network Interface SQL Server Onculeri SQL Server Öncüleri SQL Server Öncüleri Ankara SQL Server Performance sql server performans SQL Server Profiler SQL server recovery model SQL Server Reporting Services SQL Server Restore Generate Script SQL Server sa SQL Server Security SQL Server SQL DIAG sql server tarih dönüşüm işlemi sql server tarihsel veriler ile çalışma SQL Server User SQL Server yetki SQL Server yetkilendirme sql servera .net kodu ekleme SQL Serverda yetkilendirme nasıl SQL Serverda yetkilendirme nasıl yapılır sql to oracle linked server sql türkiye SQL User With Password sql yarışma SQLCMD sql'den oracle'a linked server SQLDIAG SQLDIAG Report SQLOS sqlsaturay SQLSaturday SQLSaturday #182 SQLSaturday #359 sqlsaturday #451 sqlserveronculeri ssas SSAS 2012 SSIS SSIS 2012 ssis SSMS SSMS Project SSMS Solution ssrs Stanby Database star schema STOPAT STOPBEFOREMARK STORAGE Storage Engine stored procedure stream analytics job subreports Subscriber Subscription subscriptions symmetric SYS sys.dm_db_index_physical_stats sys.dm_db_index_usage_stats sys.dm_db_missing_index_columns sys.dm_db_missing_index_details sys.dm_db_missing_index_group_stats sys.dm_db_missing_index_groups sys.server_principals sysadmin System Databases System View şifre şifreleme table table difference TableHasClustIndex TableHasIdentity TableHasPrimaryKey Tablet PC Tabular Mode Tabular Model TCP/IP TDE Tempdb time series Transaction Transactional Publication Transactional Replication Transparent Data Encryption trigger Troubleshooting TRY_CONVERT TRY_PARSE tsql t-sql T-SQL 2012 tsql mistakes Undocument union unionall Updatable ColumnStore İndex upgrade Veri ambarı veri edinme seçenekleri Veri Güvenliği Veri Hizmetleri Veri madenciliği Veri Mürekkep Oranı Veri Tabanı Yönetim Sistemleri Veri Tipi Veri Tutarlılık Modelleri Veri Yönetimi Evrimi verinin evrimi Veritabanı oluşturmak VERİTABANI YEDEKLEME STRATEJİLERİ veritabanı yedeklerinin şifrelenmesi Veritabanı Yöneticisi Veritabanı Yönetimi VeritPaq view any database Visual Studio VTYS web services Webcast Windows 7 Windows 8 Windows Authentication Windows Azure Windows Failover Clustering wmi WRITELOG xevents xp_sqlagent_enum_jobs YEDEKLEME STRATEJİLERİ Yedekli Çalışma Yetkilendirme Yiğit Aktan ysfkhvc yusuf kahveci Yüksek Erişilebilirlik Yüksek Süreklilik zip

Eksik Index’lerin (Missing Index) Belirlenip Oluşturulması Operasyonu

Ekleyen: Turgay Sahtiyan Microsoft Senior SQL Server PFE Tarih:24.08.2011 Okunma Sayısı:9683


DMV'ler ile Eksik Index'leri Sorgulama başlıklı makalemde sistemde olmayan ama olması tavsiye edilen  indexleri nasıl sorgulayabileceğimizi incelemiştik. Bu makalemde ise belirlediğimiz bu missing index’leri adım adım analiz edip create edip etmemeye karar vereceğiz. Ve create ettikten sonrada nasıl monitor edebileceğimizi görüyor olacağız. Yani baştan sona bir missing index operasyonunun nasıl yapıldığını görüyor olacağız.

Makale şu alt başlıklar altında yer alacaktır;

  1. Missing Index’lerin sorgulanması ve create edilecek index’e karar verilmesi.
  2. Create edilmesi düşünülen index’in ve bulunduğu tablonun analizi
    • Tablo kayıt sayısı ve boyut analizi
    • Tablonun üzerinde bulunan diğer index’lerin kullanım istatistikleri
    • Tablonun üzerinde bulunan index’lerin hangi kolonlar üzerinde bulunduklarının kontrolü
    • Tablonun üzerinde bulunan index’lerin Include Column içerip içermediklerinin kontrolü
  3. Tablonun query stats’larına bakılıp ilgili missing index’e sebep olan script’in bulunması.
  4. Bulunan script’in şu anki IO değerlerinin sorgulanması.
  5. Index’in create edilmesi
  6. Sorgunun IO değerine tekrar bakılması ve ne kadar düştüğünün incelenmesi.
  7. Create edilen index’in kullanım istatistiklerinin monitor edilmesi

1. Missing Index’lerin sorgulanması ve create edilecek index’e karar verilmesi

Missing Index’lerin nasıl sorgulanabileceği ile ilgili detay bilgiye şu makaleden erişebilirsiniz. Bu makalemde detaya girmeden direk missing index sorgusunu çalıştıracağız.

Daha öncesinde bir Missing Index durumu oluşturmak için AdventureWorks te bulunan Person.Address tablosuna City ve PostalCode üzerinden select çekelim. Bu kolonlar üzerinde tanımla olan bir index olmadığı için bir missing index kaydı oluşacaktır.

--Aşağıdaki select'i birden fazla kez çalıştırınız
select * from Person.Address where City='Duvall' and PostalCode='98019'

Şimdi AdventureWorks DB’si için Missing Index sorgumuzu çalıştıralım.

select DB_NAME(id.database_id) as databaseName,
 id.statement as TableName,
 id.equality_columns,
 id.inequality_columns,
 id.included_columns,
 gs.last_user_seek,
 gs.user_seeks,
 gs.last_user_scan,
 gs.user_scans,
 gs.avg_total_user_cost * gs.avg_user_impact * (gs.user_seeks + gs.user_scans)/100 as ImprovementValue  
from sys.dm_db_missing_index_group_stats gs
INNER JOIN sys.dm_db_missing_index_groups ig on gs.group_handle = ig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details id on id.index_handle = ig.index_handle
where DB_NAME(id.database_id) = 'AdventureWorks'
order by avg_total_user_cost * avg_user_impact * (user_seeks + user_scans)/100 desc

Sorgu sonucunda aşağıdaki gibi bir sonuç çıkacaktır.

Gördüğünüz gibi Person.Address tablosu üzerinde City ve PostalCode kolonları için bir missing index önerisi çıktı. Bu index olsaydı 28 kez seek edileceğini ve en son 10.12.2010 14:33 tarihinde seek edildiği bilgilerine de bu sorgu sonucunda erişebiliyoruz.

Dolayısıyla üzerinde çalışacağımız ve create etmek istediğimiz index’i belirledik. Person.Address tablosu için City ve PostalCode kolonları.

Şimdi gerçekten böyle bir index’e ihtiyaç var mı diye detay analizlerimize başlayalım.

 

2. Create edilmesi düşünülen index’in ve bulunduğu tablonun analizi

Bu başlık altında aşağıdaki detay incelemeleri yapacağız.

  • Tablo kayıt ve boyut analizi = Tablonun kayıt sayısına bakarak index’in gerekliliğinin ilk sorgulamasını yapıyoruz. Eğer ufak bir tablo ise index’in create edilmesinin çok gerekli olmadığını düşünebiliriz. Ya da boyutu çok büyükse oluşturacağımız index’in de iyi bir yer kaplayacağını düşünerek create edip etmemeyi tekrar değerlendirebiliriz. Ama ben kendi çalışmalarımda bu adıma sadece kontrol için bakıyorum. Çoğu durumda bu adım index create edip etmeme kararıma çok fazla etki etmiyor.
  • Tablonun üzerinde bulunan diğer index’lerin kullanım istatistikleri = Tabloda bulunan diğer index’lerin kullanım istatistiklerine bakıyoruz. Bu kontrol sırasında diğer index’lerin kullanım rakamlarına göre bu yeni oluşturacağımız index’in cluster index ya da non-cluster index olup olmayacağına karar verebiliriz.
  • Tablonun üzerinde bulunan index’lerin hangi kolonlar üzerinde bulunduklarının kontrolü = Tablonun hali hazırda sahip olduğu index’lerin hangi kolonlar üzerine tanımlandıklarına bakıyoruz. Belkide bizim oluşturmak istediğimiz index’i başka bir index farklı kolon sıralaması ile cover etmekte. Eğer böyle bir durum var ise index create etmemeyi düşünebiliriz.
  • Tablonun üzerinde bulunan index’lerin Include Column içerip içermediklerinin kontrolü = sp_helpindex sistem procedure’ü included column’ları vermemekte. Dolayısıyla son adım olarak bu kontrolüde yapıyoruz.

Yukarıdaki analizlerin tamamı için aşağıdaki sorgu bloğunu kullanabiliriz. Parametre olarak hangi tabloyu analiz etmek istediğimizi belirtiyoruz.

declare @tablename varchar(100)='Person.Address'

--1. Tablonun kayıt sayısına ve size ına bakılır.
exec('sp_spaceused '''+@tablename+''' ')

--2. Tablonun diğer index lerinin Index Usage Statistics lerine bakılır.
select OBJECT_SCHEMA_NAME(us.object_id),OBJECT_NAME(us.object_id) as tableName,
    i.index_id,
 i.name as indexName,
 us.last_user_seek,
 us.user_seeks,
 CASE us.user_seeks WHEN 0 THEN 0
  ELSE us.user_seeks*1.0 /(us.user_scans + us.user_seeks) * 100.0 END AS SeekPercentage,
 us.last_user_scan,
 us.user_scans,
 CASE us.user_scans WHEN 0 THEN 0
  ELSE us.user_scans*1.0 /(us.user_scans + us.user_seeks) * 100.0 END AS ScanPercentage,
 us.last_user_lookup,
 us.user_lookups,
 us.last_user_update,
 us.user_updates,
 CASE us.user_scans + us.user_seeks WHEN 0 THEN 0
  ELSE us.user_updates*1.0/(us.user_scans + us.user_seeks)*100.0 END as UpdatesPercentage 
FROM sys.dm_db_index_usage_stats us
INNER JOIN sys.indexes i ON i.object_id=us.object_id and i.index_id = us.index_id 
WHERE us.database_id = DB_ID() and OBJECT_SCHEMA_NAME(us.object_id)+'.'+OBJECT_NAME(us.object_id) = @tablename

--3. Diğer index'lerin hangi kolonlar üzerinde olduğuna bakılır.
exec('sp_helpindex '''+@tablename+''' ')

--4. Diğer index lerden included column içeren var mı yok mu diye bakılır.
select * from sys.index_columns where OBJECT_ID(@tablename)=object_id and is_included_column!=0

Sorgu sonucu şu şekilde bir sonuç olacaktır.

 

3. Tablonun query stats’larına bakılıp ilgili missing index’e sebep olan script’in bulunması

Missing index’in hangi sorgu sonucunda oluştuğunu bilmek istiyorum. Çünkü bizim yaptığımız örneğin tersine reel de ben hangi sorgudan bu index’in missing olarak belirlendiğini bilmiyorum. Bunun için sys.dm_exec_query_stats dmv’sini kullanıyorum.

select 
     st.[text],
     SUBSTRING(st.text, (qs.statement_start_offset/2)+1, 
        ((CASE qs.statement_end_offset
          WHEN -1 THEN DATALENGTH(st.text)
         ELSE qs.statement_end_offset
         END - qs.statement_start_offset)/2) + 1) AS statement_text,        
     qs.last_execution_time,
     qs.execution_count,
     qs.total_logical_reads as total_logical_read,
     qs.total_logical_reads/execution_count as avg_logical_read,
     qs.total_worker_time/1000000 as total_cpu_time_sn,
     qs.total_worker_time/qs.execution_count/1000 as avg_cpu_time_ms,
     qp.query_plan,
     qs.last_logical_reads,
     qs.plan_generation_num
from sys.dm_exec_query_stats qs
cross apply sys.dm_exec_sql_text(qs.sql_handle) st
cross apply sys.dm_exec_query_plan(qs.plan_handle) qp
where SUBSTRING(st.text, (qs.statement_start_offset/2)+1, 
        ((CASE qs.statement_end_offset
          WHEN -1 THEN DATALENGTH(st.text)
         ELSE qs.statement_end_offset
         END - qs.statement_start_offset)/2) + 1) like '%Person.Address%'

Sorgu sonucu aşağıdaki gibi bir sonuç olacaktır.

Gördüğünüz gibi ilk satırda bizi ilgilendiren script’i bulduk. Bu script 28 kez çalıştırılmış ve her çalışmada 236 logical read yapmış.

 

4.Bulunan script’in şu anki IO değerlerinin sorgulanması

Tanımlayacağımız index’in logical read değerlerinde bir değişiklik yapıp yapmadığını görmek için şu anki yaptığı IO değerine bakmak istiyorum. Bir önceki adımda ilgili script’i bulmuştum. Şimdi bu script’in IO değerlerine bakıyorum.

set statistics IO ON
set statistics profile ON
select * from Person.Address where City='Duvall' and PostalCode='98019'

Görüldüğü gibi index creatinden önce bu sorgu 236 logical read yapmakta.

 

5. Index’in create edilmesi

Bütün analizlerimizi yaptık ve index’i create etmeye karar verdik.

USE [AdventureWorks]
GO
CREATE NONCLUSTERED INDEX [IX_Address_City_PostalCode]
ON [Person].[Address] ([City],[PostalCode])

 

6.Sorgunun IO değerine tekrar bakılması ve ne kadar düştüğünün incelenmesi

Index’i create ettikten sonra tekrar IO sorgumuzu çekelim ve yapılan IO da bir iyileştirme olup olmadığını kontrol edelim.

set statistics IO ON
set statistics profile ON
select * from Person.Address where City='Duvall' and PostalCode='98019'

Gördüğünüz gibi index create’inden önce 236 olan logical read index create’inden sonra 22’ye düşmüş durumda. Bu durumda 10 kat iyileştirme yaptığımızı düşünebiliriz.

 

7.Create edilen index’in kullanım istatistiklerinin monitor edilmesi

Missing Index’leri create ettikten sonra periyoduk olarak (ben 1 haftada bir yapıyorum) create ettiğimiz indexlerin usage statistic’lerine bakıp ne kadar seek,scan aldığına, ne kadar update gördüğüne bakmakta fayda var. Bu şekilde create edip kullanılmadığını gördüğümüz index’leri drop etmeyi düşünebiliriz.

select OBJECT_NAME(us.object_id) as tableName,
 i.name as indexName,
 us.last_user_seek,
 us.user_seeks,
 CASE us.user_seeks WHEN 0 THEN 0
  ELSE us.user_seeks*1.0 /(us.user_scans + us.user_seeks) * 100.0 END AS SeekPercentage,
 us.last_user_scan,
 us.user_scans,
 CASE us.user_scans WHEN 0 THEN 0
  ELSE us.user_scans*1.0 /(us.user_scans + us.user_seeks) * 100.0 END AS ScanPercentage,
 us.last_user_lookup,
 us.user_lookups,
 us.last_user_update,
 us.user_updates
FROM sys.dm_db_index_usage_stats us
INNER JOIN sys.indexes i ON i.object_id=us.object_id and i.index_id = us.index_id 
WHERE us.database_id = DB_ID('AdventureWorks') and OBJECT_NAME(us.object_id) = 'Address'

 

Gördüğünüz gibi create ettiğimiz index çok güzel bir şekilde seek alarak kullanılmakta. Eğer seek+scan değeri update den küçük olsaydı bu index’i drop etmeyi düşünebilirdik.

 

ÖZET

Adım adım missing index operasyonunu nasıl gerçekleştirdiğimizi incelemeye çalıştık. Index kullanımı büyük projeler için çok önemli olduğundan bu kontrollerin periyodik olarak production ortamları için yapılmasının önemine tekrar vurgu yaparak yazımı noktalamak istiyorum.

 


yorum yaz

Üye Girişi

Kullanıcı Adınız

Şifreniz

Şifremi Unuttum

Arkadaşına Tavsiye Et

Tavsiye edebilmek için siteye giriş yapmalısınız