100.000 kayıt içeren MySQL tablosu sık sık sorgulandı


11

Çeşitli bilgi depolamak için yaklaşık 100 tablolar tek bir veritabanı var.

En önemli tablo, müşteri siparişlerini saklamak için kullanılan ve şu an ve büyüyen 100.000'den fazla kayıt olan sipariş tablomuzdur.

Bu tablo, gerçek zamanlı sipariş panolarından, istatistiklerden, analizlerden vb. Gereken çeşitli bilgilerin bölümleri için veritabanımızdaki en sorgulanan tablodur.

Ben düzenli olarak veritabanını izlemek ve sorunları izlemek için veritabanında yavaş sorguları etkin.

Sorguyu günlük olarak tükürmek için mysqltuner gibi komut dosyaları kullanıyorum.

Ayrıca, veritabanımızdaki en yavaş 10 sorgu hakkında bilgi toplamak için mysqlsla kullanıyorum.

sample stat
Count         : 11.48k  (30.66%)
Time          : 19.623758 s total, 1.709 ms avg, 239 µs to 2.475017 s max  (18.64%)
  95% of Time : 5.246833 s total, 481 µs avg, 239 µs to 1.095 ms max
Lock Time (s) : 14.460071 s total, 1.259 ms avg, 53 µs to 2.462555 s max  (41.38%)
  95% of Lock : 806.43 ms total, 74 µs avg, 53 µs to 137 µs max
Rows sent     : 1 avg, 0 to 9 max  (0.99%)
Rows examined : 6 avg, 1 to 28 max  (0.15%)

En yavaş sorgulananların çoğu yukarıda belirtilen sipariş tablosunu içerir. Depolama motorum olarak MyISAM kullanıyorum, böylece olası sorunlar şunlar olabilir:

  1. Masa kilitleme
  2. Endeksleme sorunları

Bu istatistikleri nasıl geliştirebilirim, bu tablolar için dizin oluşturma yaptım ve okuma sorgularını iyileştirmek için onları değiştirmeye devam ettim.

Tablo şeması

`orderid` int(11) NOT NULL AUTO_INCREMENT,
`cityid` tinyint(3) unsigned NOT NULL DEFAULT '1',
 `model_type` tinyint(1) unsigned DEFAULT '1',
`userid` int(11) DEFAULT NULL,
`usertype` char(1) DEFAULT NULL,
`time` time DEFAULT NULL,
`ordercode` char(8) DEFAULT NULL,
`restid` smallint(3) unsigned NOT NULL,
`areaid` smallint(3) unsigned DEFAULT NULL,
`restname` varchar(50) DEFAULT NULL,
`date` date NOT NULL,
`del_time` time NOT NULL,
`status` tinyint(3) unsigned NOT NULL,
`amount` float NOT NULL,
`deliverycharge` smallint(4) unsigned DEFAULT '0',
`tax` float NOT NULL,
`total` float NOT NULL,
`extras` varchar(255) DEFAULT NULL,
`requests` varchar(255) DEFAULT NULL,
`discount` float DEFAULT NULL,
`rdiscount` float DEFAULT NULL,
`reason` varchar(255) DEFAULT NULL,
`rest_order` tinyint(1) unsigned DEFAULT NULL,
`admin_user` varchar(25) DEFAULT NULL,
`mode` char(1) NOT NULL,
`priority_order` tinyint(1) unsigned DEFAULT '0',
`payment_mode` tinyint(1) unsigned DEFAULT '0',
`km` tinyint(3) unsigned DEFAULT NULL,
`order_type` tinyint(1) NOT NULL DEFAULT '1',
`coupon_discount` smallint(3) DEFAULT '0',
`pickup_time` time NOT NULL,
PRIMARY KEY (`orderid`),
KEY `cityid` (`cityid`),
KEY `date_3` (`date`,`status`,`mode`),
KEY `orderid` (`orderid`),
KEY `time` (`time`),
KEY `userid` (`userid`,`usertype`),
KEY `restid` (`restid`,`date`,`status`)

yavaş günlük sorgusu

SELECT `a`.`orderid`, `a`.`date`, `a`.`status`, `a`.`restname`, `a`.`admin_user`, `a`.`model_type`, `b`.`name` as cityname
FROM `tk_order_queue` AS a
INNER JOIN `tk_cities` AS b ON `a`.`cityid` = `b`.`id`
WHERE `a`.`date` =  '2012-06-30'
AND `a`.`status` =  0
AND `a`.`mode` =  1
ORDER BY `a`.`orderid` desc;

Lütfen çalıştırın SHOW CREATE TABLE orders\Gve soruya gönderin
RolandoMySQLDBA

2
Bunu yanlış mı okuyorum, yoksa ortalama sorgu süresi 1.7 ms mi? Neden dünyada hızlanmaya bakasın ki?
Philᵀᴹ

Neden yavaş sorgu günlüklerinde görünüyor biraz karışık.
sheldon

@RolandoMySQLDBA şema ekledim
sheldon

1
Tabloda dizinleriniz olması, sorgularınız için doğru dizinler oldukları anlamına gelmez. Birkaç yavaş sorgu örneği ve bunların EXPLAIN çıktısını gönderebilir misiniz? Ayrıca, siparişler tablosu ne sıklıkta güncellenir?
bobwienholt

Yanıtlar:


8

Mevcut dizinlerinizin EXPLAIN planlarında bunları destekleyebildiğinden emin olmak için tüm sorgularınızın WHERE yan tümcelerini ve GROUP BY ve ORDER BY ifadelerini karşılaştırmanız gerekir.

Dün bu soruyu cevapladım: InnoDB vs MyISAM birçok dizin ile

Bu soruda MyISAM tablosuna da yapabileceğiniz bir şey yapmayı önerdim

ALTER TABLE orders ROW_FORMAT=Fixed;

Bu, tüm VARCHAR'lara CHAR olarak davranacaktır. Her satır aynı uzunlukta olacaktır. Bu, disk alanını% 80 -% 100 oranında artıracaktır. Tablonuz, satır düzeni için satır sayısının maksimum boyutuna ulaşacaktır. Tablonuz iki veya üç kat büyüklükte olabilir.

Avantaj nerede? Daha sonra MyISAM tablonuz başka bir şey değiştirmeden% 20 -% 30 arasında daha hızlı okunacak / yazılacaktır.

Bunu 72,73. Sayfalarda MySQL Veritabanı Tasarımı ve Ayarı'ndan öğrendim .

Geçmişte bunun hakkında yazmıştım:


Ayrıntılı açıklama için teşekkürler, evet tabloya eklenen dizinler, sistemimizde kullanılan ifadeler, seçimler, gruplama ve sıralama göre kullanılan sorgulara dayanmaktadır. Dizin günlükleri olmadan sorguları izlemek ve tablolar buna göre güncellenmektedir.
sheldon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.