Zapytanie Mysql zajmuje dużo czasu, gdy używana jest zmienna

0

Pytanie

U mnie było to wydarzenie mysql i do dzisiaj mam okropny dzień o 9:45 rano.

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;

w zapytaniu [ym-to rok, i ym jest indeksowana], kiedy zastępuję zmienną @v_ym, wykonywane pełne skanowanie tabeli, a tabela jest zablokowana do dalszych wstawek. gdzie, jak i kiedy zadałem wartość bezpośrednio, używa indeksu, i wniosek jest szybka.

Tabela zawiera ponad 10 milionów płyt.

Utworzyć tabelę-to

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

Plan wyjaśnienia dla 2 - go rodzaju:

enter image description here

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

Najlepsza odpowiedź

1

Jaki procent tabeli znajduje się w bieżącym miesiącu"? Jeżeli jest to więcej niż coś w stylu 20%, poprawki, nie-skanowanie tabeli, najprawdopodobniej, będzie szybciej. Jeśli jest to mniej niż 20%, to, jak podejrzewasz, @variables może być zły. W takim przypadku zmień test na

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

Znacznie szybciej byłoby utworzyć i aktualizować tabelę przestawną z PRIMARY KEY dnia i nazwy ssaname. To będzie mieć sumy za każdy dzień. On będzie się utrzymywać lub w miarę tego, jak dane INSERTed lub każdej nocy po północy.

Następnie wniosek do 9:45 staje się bardzo szybki. Może być tak szybko, że nawet nie trzeba to robić raz dziennie, a zamiast tego "na żądanie".

Jeszcze jedno dyskusja: http://mysql.rjweb.org/doc.php/summarytables

Proponuję użyć NOW() zamiast SYSDATE() -- Pierwszy jest stały na całej wypowiedzi; po drugie-nie.

bts_faults wygląda na to, że może on być wielkości w terabajtów. Jeśli tak, to prawdopodobnie nie chcesz, aby tutaj sposoby mniej.

Jeśli wartość Auto_inc wynosi 3,8 B, ale w nim tylko 10 wierszy, czy to oznacza, że usuwasz stare dane? Chcesz porozmawiać o przyspieszenie usuwania? (Zacznij nowe pytanie, jeśli to zrobisz.)

2021-11-21 06:31:56

jeszcze nie pracuję ze zmianą teraz(), 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; On nie korzysta z indeksu , który został utworzony w ym, gdzie, ponieważ to samo zapytanie działa szybko, gdy WYJMOWANIE(ГОД_МЕСЯЦ Z (DATE_SUB(NOW(), INTERVAL 1 DZIEŃ))) zamiana 202111, tabela zawiera tylko 18 milionów danych.
sriman narayana

@шриманнараяна - A... myślę, że widzę problemu. U mnie był "varchar = stała data", zmieńmy go na "varchar = stała data". Zmieniłem swoją Odpowiedź.
Rick James

@srimannarayana - Proszę dodać poprawioną SELECT i jego EXPLAIN na twoje Pytanie.
Rick James

W kwestii dodano objaśniający paln 2 zapytań
sriman narayana

@srimannarayana - nie widzę, aby CAST służy do uzyskania wartości. Wygląda na to, że to problem z typem danych, dlatego potrzebuję obsada.
Rick James

W innych językach

Ta strona jest w innych językach

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