MySQL için Azure Veritabanı - Esnek Sunucu sorunlarını gidermeye yönelik en iyi yöntemler

ŞUNLAR IÇIN GEÇERLIDIR: MySQL için Azure Veritabanı - Tek Sunucu MySQL için Azure Veritabanı - Esnek Sunucu

Önemli

MySQL için Azure Veritabanı tek sunucu kullanımdan kaldırma yolundadır. Esnek MySQL için Azure Veritabanı sunucuya yükseltmenizi kesinlikle öneririz. MySQL için Azure Veritabanı esnek sunucuya geçiş hakkında daha fazla bilgi için bkz. MySQL için Azure Veritabanı Tek Sunucu'ya neler oluyor?

MySQL için Azure Veritabanı esnek sunucu veritabanlarınızın sorunsuz çalışmasını sağlamak için aşağıdaki bölümleri kullanın ve şemaların en iyi şekilde tasarlandığından ve uygulamalarınız için en iyi performansı sağladığından emin olmak için bu bilgileri yol gösteren ilkeler olarak kullanın.

Dizin sayısını denetleme

Yoğun bir veritabanı ortamında yüksek G/Ç kullanımı gözlemleyebilir ve bu da veri erişim desenlerinin zayıf olduğunu gösterebilir. Kullanılmayan dizinler, disk alanı ve önbellek tükettiği ve yazma işlemlerini yavaşlatan (INSERT /DELETE/ UPDATE) performans üzerinde olumsuz bir etkiye sahip olabilir. Kullanılmayan dizinler gereksiz yere daha fazla depolama alanı tüketir ve yedekleme boyutunu artırır.

Herhangi bir dizini kaldırmadan önce, artık kullanılmadığını doğrulamak için yeterli bilgi topladığınızdan emin olun. Bu doğrulama, yalnızca üç aylık veya yıllık olarak çalışan bir sorgu için kritik öneme sahip bir dizini yanlışlıkla kaldırmaktan kaçınmanıza yardımcı olabilir. Ayrıca, bir dizinin benzersizliği veya sıralamayı zorlamak için kullanılıp kullanılmadığını da göz önünde bulundurun.

Dekont

Dizinleri düzenli aralıklarla gözden geçirmeyi ve tablo verilerinde yapılan değişikliklere göre gerekli güncelleştirmeleri gerçekleştirmeyi unutmayın.

SELECT object_schema, object_name, index_name FROM performance_schema.table_io_waits_summary_by_index_usage WHERE index_name IS NOT NULL AND count_star = 0 ORDER BY object_schema, object_name;

(veya)

use information_schema; select tables.table_name, statistics.index_name, statistics.cardinality, tables.table_rows from tables join statistics on (statistics.table_name = tables.table_name and statistics.table_schema = '<YOUR DATABASE NAME HERE>' and ((tables.table_rows / statistics.cardinality) > 1000));

Sunucudaki en yoğun dizinleri listeleme

Aşağıdaki sorgunun çıktısı, veritabanı sunucusundaki tüm tablo ve şemalarda en çok kullanılan dizinler hakkında bilgi sağlar. Bu bilgiler, yazma işlemlerinin her bir dizine göre okumalara oranını ve okumalar için gecikme sürelerinin yanı sıra temel tablo ve bağımlı sorgular için daha fazla ayarlama yapılması gerektiğini gösterebilen tek tek yazma işlemlerini belirlemede yararlıdır.

SELECT 
object_schema AS table_schema, 
object_name AS table_name, 
index_name, count_star AS all_accesses, 
count_read, 
count_write, 
Concat(Truncate(count_read / count_star * 100, 0), ':', 
Truncate(count_write / count_star * 100, 0)) AS read_write_ratio, 
 count_fetch AS rows_selected , 
 count_insert AS rows_inserted, 
 count_update AS rows_updated, 
 count_delete AS rows_deleted, 
 Concat(Round(sum_timer_wait / 1000000000000, 2), ' s') AS total_latency , 
 Concat(Round(sum_timer_fetch / 1000000000000, 2), ' s') AS select_latency, 
 Concat(Round(sum_timer_insert / 1000000000000, 2), ' s') AS insert_latency, 
Concat(Round(sum_timer_update / 1000000000000, 2), ' s') AS update_latency, 
 Concat(Round(sum_timer_delete / 1000000000000, 2), ' s') AS  delete_latency 
FROM performance_schema.table_io_waits_summary_by_index_usage 
WHERE index_name IS NOT NULL AND count_star > 0 
ORDER BY sum_timer_wait DESC 

Birincil anahtar tasarımını gözden geçirme

MySQL için Azure Veritabanı esnek sunucu, ilkel olmayan tüm tablolar için InnoDB depolama altyapısını kullanır. InnoDB ile veriler, B Ağacı yapısı kullanılarak kümelenmiş dizin içinde depolanır. Tablo, birincil anahtar değerlerine göre fiziksel olarak düzenlenmiştir ve bu da satırların birincil anahtar sırasına göre depolandığı anlamına gelir.

InnoDB tablosundaki her ikincil anahtar girişi, verilerin depolandığı birincil anahtar değerine yönelik bir işaretçi içerir. Başka bir deyişle, ikincil dizin girdisi, girdinin işaret ettiği birincil anahtar değerinin bir kopyasını içerir. Bu nedenle, birincil anahtar seçeneklerinin tablolarınızdaki depolama ek yükü miktarı üzerinde doğrudan etkisi vardır.

Anahtar gerçek verilerden türetilirse (örneğin, kullanıcı adı, e-posta, SSN vb.), buna doğal anahtar adı verilir. Anahtar yapaysa ve verilerden türetilmemişse (örneğin, otomatik olarak belirlenen bir tamsayı), yapay anahtar veya vekil anahtar olarak adlandırılır.

Genellikle doğal birincil anahtarları kullanmaktan kaçınması önerilir. Bu anahtarlar genellikle çok geniştir ve bir veya birden çok sütundan uzun değerler içerir. Bu da her ikincil anahtar girişine kopyalanan birincil anahtar değeriyle ciddi depolama ek yüküne neden olabilir. Ayrıca, doğal anahtarlar genellikle önceden belirlenmiş bir sırayı izlemez; bu da performansı önemli ölçüde azaltır ve satırlar eklendiğinde veya güncelleştirildiğinde sayfa parçalanması tetikler. Bu sorunları önlemek için doğal anahtarlar yerine monoton olarak artan vekil anahtarları kullanın. Otomatik tamsayı (büyük)tamsayı sütunu, monoton olarak artan vekil anahtarın iyi bir örneğidir. Belirli bir sütun bileşimine ihtiyacınız varsa, benzersiz olun, bu sütunları benzersiz bir ikincil anahtar olarak bildirin.

Bir uygulama oluşturmanın ilk aşamalarında, tablonuzun iki milyar satıra yaklaşmaya başladığı bir zamanı hayal etmek için ileriye dönük düşünmeyebilirsiniz. Sonuç olarak, id (birincil anahtar) sütununun veri türü için imzalı bir 4 baytlık tamsayı kullanmayı tercih edebilirsiniz. Tüm tablo birincil anahtarlarını denetleyerek yüksek hacim veya büyüme potansiyeline uyum sağlamak için 8 baytlık tamsayı (BIGINT) sütunlarını kullanmaya geçtiğinden emin olun.

Dekont

Veri türleri ve bunların en yüksek değerleri hakkında daha fazla bilgi için MySQL Başvuru Kılavuzu'nda Veri Türleri'ne bakın.

Kapsayan dizinleri kullanma

Önceki bölümde MySQL'deki dizinlerin B Ağaçları olarak nasıl düzenlendiği ve kümelenmiş bir dizinde yaprak düğümlerin temel alınan tablonun veri sayfalarını nasıl içerdiği açıklanmaktadır. İkincil dizinler kümelenmiş dizinlerle aynı B ağacı yapısına sahiptir ve bunları kümelenmiş dizin veya yığın içeren bir tabloda veya görünümde tanımlayabilirsiniz. İkincil dizindeki her dizin satırı, kümelenmemiş anahtar değerini ve bir satır bulucuyu içerir. Bu bulucu, anahtar değerine sahip kümelenmiş dizin veya yığındaki veri satırına işaret etmektedir. Sonuç olarak, ikincil dizin içeren tüm aramaların birincil anahtar değerini almak için dal düğümleri aracılığıyla kök düğümden başlayarak doğru yaprak düğüme geçmesi gerekir. Ardından Sistem, veri satırını almak için birincil anahtar dizininde rastgele bir GÇ okuması yürütür (bir kez daha dal düğümleri aracılığıyla kök düğümden doğru yaprak düğüme geçer).

Veri satırını almak için birincil anahtar dizininde bu ek rastgele GÇ okumasını önlemek için, sorgunun gerektirdiği tüm alanları içeren bir kapsayan dizin kullanın. Genellikle bu yaklaşımın kullanılması G/Ç'ye bağlı iş yükleri ve önbelleğe alınmış iş yükleri için yararlıdır. Bu nedenle en iyi yöntem olarak, dizinleri kapsamayı kullanın çünkü bunlar belleğe sığar ve tüm satırları taramaktan daha küçük ve okuması daha verimlidir.

Örneğin, 1 Ocak 2000'den sonra şirkete katılan tüm çalışanları bulmak için kullandığınız bir tabloyu düşünün.

mysql> show create table employee\G
*************************** 1. row ***************************
       Table: employee
Create Table: CREATE TABLE `employee` (
  `empid` int(11) NOT NULL AUTO_INCREMENT,
  `fname` varchar(10) DEFAULT NULL,
  `lname` varchar(10) DEFAULT NULL,
  `joindate` datetime DEFAULT NULL,
  `department` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`empid`)
  ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)`

`mysql> select empid, fname, lname from employee where joindate > '2000-01-01';

Bu sorguda bir EXPLAIN planı çalıştırırsanız, şu anda dizin kullanılmadığını ve çalışan kayıtlarını filtrelemek için tek başına where yan tümcesinin kullanıldığını gözlemlersiniz.

mysql> EXPLAIN select empid, fname, lname from employee where joindate > '2000-01-01'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: employee
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3
     filtered: 33.33
        Extra: Using where
1 row in set, 1 warning (0.01 sec)

Ancak where yan tümcesindeki sütunu kapsayan bir dizin eklediyseniz, yansıtılan sütunlarla birlikte, sütunları çok daha hızlı ve verimli bir şekilde bulmak için dizinin kullanıldığını görürsünüz.

mysql> CREATE INDEX cvg_idx_ex ON employee (joindate, empid, fname, lname);

Şimdi, AYNı sorguda EXPLAIN planını çalıştırırsanız, "Dizin Kullanma" değeri "Ek" alanında görünür; başka bir deyişle InnoDB daha önce oluşturduğumuz dizini kullanarak sorguyu yürütür ve bu da bunu kapsayan bir dizin olarak onaylar.

mysql> EXPLAIN select empid, fname, lname from employee where joindate > '2000-01-01'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: employee
   partitions: NULL
         type: range
possible_keys: cvg_idx_ex
          key: cvg_idx_ex
      key_len: 6
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using where; Using index
1 row in set, 1 warning (0.01 sec)

Dekont

Sorguyu doğru şekilde sunmak için kapsayan dizindeki sütunların doğru sırasını seçmek önemlidir. Genel kural, önce filtreleme (WHERE yan tümcesi), ardından sıralama/gruplandırma (ORDER BY ve GROUP BY) ve son olarak veri projeksiyonu (SELECT) için sütunları seçmektir.

Önceki örnekte, bir sorgu için kapsayan dizine sahip olmanın daha verimli kayıt alma yolları sağladığını ve yüksek oranda eşzamanlı veritabanı ortamında performansı iyileştirdiğini gördük.

Sonraki adımlar

En önemli sorularınızın eş yanıtlarını bulmak veya soru göndermek veya yanıtlamak için Stack Overflow'u ziyaret edin.