Запрос Mysql занимает много времени, когда используется переменная

0

Вопрос

У меня было событие mysql, и сегодня у меня жуткий день в 9:45 утра.

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;

в запросе [ym-это год, и ym индексируется], когда я заменяю переменную @v_ym, выполняется полное сканирование таблицы, и таблица блокируется для дальнейших вставок. где, как и когда я задал значение напрямую, он использует индекс, и вывод выполняется быстро.

Таблица содержит более 10 миллионов записей.

Создать таблицу-это

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 - го типа:

enter image description here

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

Лучший ответ

1

Какой процент таблицы находится в "текущем месяце"? Если это больше, чем что-то вроде 20%, то исправления нет-сканирование таблицы, скорее всего, будет быстрее. Если это меньше 20%, то, как вы подозреваете, @variables может быть злодеем. В этом случае измените тест на

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

Гораздо быстрее было бы создать и поддерживать сводную таблицу с PRIMARY KEY дня и имени ssaname. Это будет иметь промежуточные итоги за каждый день. Он будет сохраняться либо по мере того, как данные INSERTed или каждую ночь после полуночи.

Затем запрос в 9:45 становится очень быстрым. Может быть, так быстро, что вам даже не нужно делать это один раз в день, а вместо этого "по требованию".

Еще одно обсуждение: http://mysql.rjweb.org/doc.php/summarytables

Я предлагаю вам использовать NOW() вместо SYSDATE() -- Первое является постоянным на протяжении всего высказывания; второе-нет.

bts_faults похоже, что он может быть размером в терабайт. Если это так, то вы, вероятно, не хотите, чтобы здесь способы сделать меньше.

Если значение Auto_inc равно 3,8 B, но в нем всего 10 строк, означает ли это, что вы удаляете "старые" данные? Вы хотите обсудить ускорение удаления? (Начните новый вопрос, если вы это сделаете.)

2021-11-21 06:31:56

все еще не работаю с изменением сейчас(), 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; Он не использует индекс , созданный на ym, где, поскольку тот же запрос работает быстро, когда ИЗВЛЕЧЕНИЕ(ГОД_МЕСЯЦ ИЗ (DATE_SUB(СЕЙЧАС(), ИНТЕРВАЛ 1 ДЕНЬ))) заменяется 202111, таблица содержит только 18 миллионов данных.
sriman narayana

@шриманнараяна - А... Я думаю, что вижу проблему. У меня был "varchar = постоянная дата", давайте изменим его на "varchar = постоянная дата". Я изменил свой Ответ.
Rick James

@srimannarayana - Пожалуйста, добавьте исправленную SELECT и его EXPLAIN на ваш Вопрос.
Rick James

В вопросе добавлен поясняющий paln для 2 запросов
sriman narayana

@srimannarayana - Я не вижу, чтобы CAST используется для получения значения. Похоже, это проблема с типом данных, поэтому мне нужен актерский состав.
Rick James

На других языках

Эта страница на других языках

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