MySQL çok basit SELECT sorgularında son derece yavaş


10

InnoDB motoru ile verilerini MySQL 5.5 veritabanına kaydeden sanal bir makinede çalışan basit bir web uygulamamız var. Her şey yaklaşık üç yıl boyunca iyi çalıştı, ama aniden aşırı yavaşladı.

Örneğin, adresleri tutan çok basit bir tablo var:

CREATE TABLE `addresses` (
  `address_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) CHARACTER SET latin1 NOT NULL,
  `firstname` varchar(64) CHARACTER SET latin1 NOT NULL,
  `street` varchar(64) CHARACTER SET latin1 NOT NULL,
  `housenumber` varchar(16) CHARACTER SET latin1 NOT NULL,
  `zip` varchar(5) CHARACTER SET latin1 NOT NULL,
  `city` varchar(64) CHARACTER SET latin1 NOT NULL,
  `email` varchar(64) CHARACTER SET latin1 NOT NULL,
  `phone` varchar(16) CHARACTER SET latin1 NOT NULL,
  `birthdate` date NOT NULL,
  PRIMARY KEY (`address_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

Bu tablo yaklaşık 800 giriş tutmaktadır ki bu gerçekten fazla değildir. Ancak sorguyu çalıştırmak

SELECT * FROM addresses

Test amaçlı olarak, hiç bitmiyor gibi görünüyor. Bunu sunucunun üzerindeki mysql CLI ile kontrol ettim: Tablonun bazı satırlarını çıktılar ve daha sonra sonraki satırları çıkana kadar çok bekler.

Bu yüzden belki de veri gönderme aşamasında bir problemdir, ama emin değilim.

VM 2GB RAM'e sahiptir ve sadece 320MB kullanılır. CPU ayrıca çok düşük% 1-2 oranında çalışır. mytop sunucuyu engelleyen başka sorguları göstermez. BT yöneticisi donanım tarafında hiçbir şey değiştirmediklerini söyledi.

Zaten veritabanı sunucusunu yeniden başlatmak, sanal makineyi yeniden başlatmak gibi bir şey denedim. Hiçbir şey yardımcı olmadı.

Düzenle:

EXPLAIN SELECT * FROM addresses

bana bu sonucu verir:

+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | addresses | ALL  | NULL          | NULL | NULL    | NULL |  793 |       |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

Sanal Kutu, Xen veya başka bir şey? Ana bilgisayar diski nasıl kurulur? aynı kutuda yavaş çalışan başka VM'ler var mı? Bu soruları cevaplamak cevabı ortaya çıkarabilir
Matt

Ben hipervizörün sahibi değilim, bu yüzden buna gerçekten cevap veremiyorum. Zaten hiper yöneticinin yöneticisine son değişiklikleri biliyorlar mı diye sordum, ama hayır dedi.
tabb

yapabiliyorsanız, mysql'yi kapatın ve bazı disk ve bellek kıyaslamalarını çalıştırın. Karmaşık olmak zorunda değil. Fikir, mysql ile ilgili bir sorun, belki de aşağıdaki cevapta belirtildiği gibi dizin sorunu veya daha yaygın olup olmadığını izole etmektir.
Matt

İyi bir nokta, ben muhtemelen bir mysql sorun değil deneyimli. Koşu mysql -u username -ppassword mydb -e 'SELECT * FROM addressesyavaş çıktı, ancak "> test.txt` eklenir, çok hızlı çalışır. Şimdi bu muhtemelen farklı bir soru olurdu !? Bunu nasıl araştırabilirim?
Tabb

Hiper yöneticinin sahibiyle iletişime geçin ve günlüklerde herhangi bir hata olup olmadığını kontrol etmelerini isteyin. Özellikle disk hataları. Ona belirtilerini söyle. Şimdi yedekle.
Matt

Yanıtlar:


13

Cpu yükü düşükse, bu eksik dizinlerle ilgili herhangi bir sorun olmadığını gösterir, bu durumda sorgunun daha fazla cpu ve disk erişimi alması gerekir. Ayrıca 3 yıl boyunca iyi çalıştığını söyledin.

Genel disk erişim hızını (özellikle veritabanının bulunduğu bölümde) kontrol ettiniz mi? Örneğin, dd buradaki gibi kullanmak . Tanımladığınız şey ölü disk veya yarı ölü baskın gibi geliyor. Umarım yedek var mı?


İyi bir noktaya değindin. Ana bilgisayardaki bir disk hatası kadar basit bir şey olabilir.
Matt

9

Birkaç şeyi deneyebilirsiniz,

  1. Dizin ayarlarınız var mı?

Endeksleme, önce tam bir tablo taraması yapmadan kayıtları hızlı bir şekilde bulmayı mümkün kılar, yürütme sürelerini önemli ölçüde azaltır.

CREATE INDEX idx_name ON addresses(name);
  1. Sorguyu çalıştırmadan önce EXPLAIN anahtar sözcüğünü kullanın,

Bir SELECT sorgusu önünde kullanıldığında, MySQL'in sorguyu nasıl yürütmeyi planladığını ve bitmeden önce işlemesi gereken satır sayısını açıklar.

  1. Mysql.ini dosyasında bazı değişiklikler yapın, eğer bir VM RAM'i arttırır ve mysql.ini'nizi performansın artıp artmadığını görmek için yapılandırın.

Orada size yol gösterebilecek birçok MySQL optimizer var.

Yardım edin bu yardımcı olur


Tamam, ama oldukça küçük bir tabloda (<800 satır) bir dizin oluşturmak ihtiyacım kadar yararlı görünmüyor. Yukarıda belirtilen sorgunun tamamlanması bir dakikadan fazla sürer. Böyle küçük bir tablonun tam masa taraması çok uzun sürmemelidir.
tabb

Yani ... dizinleri eklediniz mi? Sorunun ne olduğundan emin değilseniz, temelden başlayıp aşağı inerim. Dizin eklemek, yalnızca doğru şekilde yapılırsa performansı artırır.
Anthony Fornito

Evet, ad sütununa bir dizin ekledim. Ancak yukarıdaki sorgumda herhangi bir kısıtlayıcı WHERE cümlesi bile yok, bu yüzden tüm tabloyu okumak ve yazdırmak zorunda kalacak. Eklenen dizin yardımcı olmadı.
tabb

Yukarıdaki EXPLAIN sorgusunun sonucunu ekledim. Bu bana iyi geliyor, ancak performans hala çok düşük. Sanallaştırma yöneticisinin yöneticisi olmadığım için RAM'i artıramıyorum. Ancak htop, 2050MB RAM'den yalnızca 307MB'nin kullanıldığını gösterir.
Tabb

Dizinler hakkında gerçekten hangi sütunları endekslemek hakkında düşünmek gerekir, sadece her şeyi indekslemek, en büyük miktarda olanları endekslemek istemiyorum, bu konuda bazı vahşi varsayımlar yapıyorum ama ben nameve 'firstname' ile başlar. İkincisi, dizine ekleme işlemini doğru yaptığınızdan emin misiniz? possible_keys: NULL sütun NULL ise, alakalı dizin bulunamadığını gösterir.
Anthony Fornito
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.