Mysql Sorgusu, değişkeni kullanırken uzun zaman alıyor

0

Soru

Bir mysql etkinliğim vardı ve ürkütücü bir gün saat 9: 45'te çalışıyor.

Begin
 SET @v_ym :=(SELECT extract(year_month from DATE_SUB(SYSDATE(),INTERVAL 1 DAY)));
 SELECT CAST(@ym AS CHAR);
 select ssaname,extract(year_month from date_sub(sysdate(),interval 1 day)) ym,
        omcr.btscount_ssa(ssaname) btscount,sum(case when duration>30 then duration else 0 end) dur_30 from
        btsoutage.bts_faults 
        where ym=@v_ym  and ssaname is not null
        group by ssaname;
END;

sorguda [ym yıllıktır ve ym dizine eklenir] @ v_ym değişkeniyle değiştirdiğimde tam tablo taraması yapıyor ve tablo daha fazla ekleme için kilitleniyor. değeri doğrudan verdiğimde olduğu gibi dizin kullanıyor ve çıktı hızlı.

Tablo 10 milyondan fazla kayıt içeriyor.

Tablo oluştur

CREATE TABLE IF NOT EXISTS `bts_faults` (
  `bts_name` varchar(250) DEFAULT NULL,
  `make` varchar(10) DEFAULT NULL,
  `occuredtime` datetime DEFAULT NULL,
  `clearedtime` datetime DEFAULT NULL,
  `duration` int(10) DEFAULT NULL,
  `reason` varchar(100) DEFAULT NULL,
  `site_type` varchar(10) DEFAULT NULL,
  `tech` varchar(5) DEFAULT NULL,
  `fault_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `ssaname` varchar(20) DEFAULT NULL,
  `fault_type` int(1) DEFAULT '0',
  `remarks` varchar(250) DEFAULT NULL,
  `bts_section` varchar(100) DEFAULT NULL,
  `vendor` varchar(50) DEFAULT NULL,
  `occureddate` date DEFAULT NULL,
  `cleareddate` date DEFAULT NULL,
  `ym` varchar(6) DEFAULT NULL,
  `updatedate` datetime DEFAULT NULL,
  `USERNAME` varchar(100) DEFAULT NULL,
  `mask` int(1) DEFAULT '0',
  `mask_cat` varchar(10) DEFAULT NULL,
  `outage_cat` varchar(20) DEFAULT NULL,
  `site_category` varchar(50) DEFAULT NULL,
  `escalated_time` datetime DEFAULT NULL,
  `zone` varchar(20) DEFAULT NULL,
  `zone_fault_reason` varchar(500) DEFAULT NULL,
  `zone_fault_remarks` varchar(500) DEFAULT NULL,
  `zone_username` varchar(20) DEFAULT NULL,
  `zone_updatetime` datetime DEFAULT NULL,
  `zone_fault_duration` int(11) DEFAULT NULL,
  `fault_category` varchar(250) DEFAULT NULL,
  `remarks_1` varchar(2500) DEFAULT NULL,
  PRIMARY KEY (`fault_id`),
  UNIQUE KEY `UIDX_BTS_FAULTS` (`bts_name`,`occuredtime`),
  KEY `indx_btsfaults_ym` (`ym`),
  KEY `indx_btsfaults_cleareddate` (`cleareddate`),
  KEY `Index_btsfaults_btsname` (`bts_name`),
  KEY `index_btsfaults_ssaname` (`ssaname`),
  KEY `indx_btsfaults_occureddate` (`occureddate`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3807469710 DEFAULT CHARSET=latin1

2 Tipi için Açıklama Planı şunlardır

enter image description here

events mysql
2021-11-20 18:59:15
1

En iyi cevabı

1

Tablonun yüzde kaçı "geçerli ay"içinde? Bu %20 gibi bir şeyden daha fazlaysa, düzeltme yoktur-bir tablo taramasının daha hızlı olması muhtemeldir. Eğer %20'den az ise, şüphelendiğiniz gibi, @ variables kötü adam olabilir. Bu durumda, testi şu şekilde değiştirin:

 WHERE ym = CAST(
          extract(year_month from DATE_SUB(SYSDATE(),INTERVAL 1 DAY))
                 AS CHAR)
   AND ...

Bir Özet Tablo oluşturmak ve sürdürmek çok daha hızlı olacaktır. PRIMARY KEY gün ve ssaname. Bu, her gün için alt toplamlara sahip olacaktır. Veriler olduğu gibi korunacaktır INSERTed ya da her gece gece yarısından sonra.

Sonra 9: 45 sorgusu çok hızlı olur. Belki o kadar hızlı ki, günde sadece bir kez yapmanıza bile gerek yok, bunun yerine "talep üzerine".

Daha fazla tartışma: http://mysql.rjweb.org/doc.php/summarytables

Kullanmanızı öneririm NOW() yerine SYSDATE() -- Birincisi bir ifade boyunca sabittir; ikincisi değil.

bts_faults bir terabayt büyüklüğünde olabilir. Eğer öyleyse, muhtemelen burada daha küçük yapmanın yollarını istemezsiniz.

Auto_ınc değeri 3.8 B'de ise, ancak yalnızca 10M satır varsa, bu 'eski' verileri temizlediğiniz anlamına mı geliyor? Silmeleri hızlandırmayı tartışmak ister misin? (Bunu yaparsanız yeni bir Soru başlatın.)

2021-11-21 06:31:56

hala şu anki değişiklikle çalışmıyor(), select ym, ssaname, omcr.btscount_ssa(ssaname) btscount,sum(case when duration>30 then duration else 0 end) dur_30 from btsoutage.bts_faults where ym=EXTRACT(YEAR_MONTH FROM (DATE_SUB(NOW(), INTERVAL 1 DAY)))group by ym, ssaname; Aynı sorgunun EXTRACT(YEAR_MONTH FROM (DATE_SUB(NOW (), INTERVAL 1 DAY))) 202111 ile değiştirildiğinde hızlı çalıştığı ym'de oluşturulan dizini kullanmıyor Tablo yalnızca 18 milyon veri içeriyor.
sriman narayana

@ srimannarayana-Ah... Sanırım sorunu anlıyorum. "Varchar = date-constant" vardı, onu "varchar = char-constant"olarak değiştirelim. Cevabımı değiştirdim.
Rick James

@srimannarayana-Lütfen gözden geçirilmiş olanı ekleyin SELECT ve onun EXPLAIN sizin için bir Soru.
Rick James

Soruya 2 sorgu için explaın paln eklenir
sriman narayana

@srimannarayana - Göremiyorum CAST olmanın değerini almak için kullanılır. Bu bir veri türü sorunu gibi görünüyor, bu yüzden oyuncu kadrosuna ihtiyacım var.
Rick James

Diğer dillerde

Bu sayfa diğer dillerde

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................