programing

반환할 열을 추가할 때 Mysql 쿼리가 느려지는 이유는 무엇입니까?

nicescript 2023. 1. 3. 21:58
반응형

반환할 열을 추가할 때 Mysql 쿼리가 느려지는 이유는 무엇입니까?

실행 속도가 느린 쿼리가 있습니다(Mysql 8과 MariaDB 10 모두).

    select SQL_NO_CACHE UNIX_TIMESTAMP(created_at)* 1000 AS x,
           value AS y, day(created_at), month(created_at), year(created_at) 
    from `portfolios` 
    where `user_id` = 3 and (created_at)>( CURDATE() - INTERVAL 1 MONTH) 
    group by day(created_at),month(created_at), year(created_at) 
    order by `created_at` asc;

선택 항목에서 '값' 열을 제거하면 빠르게 실행됩니다.

표는 다음과 같습니다.

portfolios | CREATE TABLE `portfolios` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
  `value` decimal(15,8) NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `portfolios_user_id_created_at_index` (`user_id`,`created_at`),
  KEY `portfolios_user_id_updated_at_index` (`user_id`,`updated_at`),
  KEY `portfolios_id_user_id_updated_at_index` (`id`,`user_id`,`updated_at`),
  KEY `portfolios_user_id_index` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11767164 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

테이블에는 약 1200만 개의 행이 있습니다.

설명 실행('값' 열 없음):

| id   | select_type | table      | type  | possible_keys                                                                                    | key                                 | key_len | ref  | rows   | Extra                                                     |
+------+-------------+------------+-------+--------------------------------------------------------------------------------------------------+-------------------------------------+---------+------+--------+-----------------------------------------------------------+
|    1 | SIMPLE      | portfolios | range | portfolios_user_id_created_at_index,portfolios_user_id_updated_at_index,portfolios_user_id_index | portfolios_user_id_created_at_index | 9       | NULL | 183996 | Using where; Using index; Using temporary; Using filesort |

설명 실행('값' 열 사용):

| id   | select_type | table      | type  | possible_keys                                                                                    | key                                 | key_len | ref  | rows   | Extra                                                  |
+------+-------------+------------+-------+--------------------------------------------------------------------------------------------------+-------------------------------------+---------+------+--------+--------------------------------------------------------+
|    1 | SIMPLE      | portfolios | range | portfolios_user_id_created_at_index,portfolios_user_id_updated_at_index,portfolios_user_id_index | portfolios_user_id_created_at_index | 9       | NULL | 184038 | Using index condition; Using temporary; Using filesort |

따라서 이 열을 쿼리에 추가하면 '어디서, 인덱스 사용'을 중지하고 '인덱스 조건 사용'을 시작하는 것 같습니다.

선택 항목에 열을 추가하는 것만으로 속도가 느려지는 이유를 잘 모르겠습니다(약 .3에 비해 15초).테이블 크기 때문일까요?

어떻게 하면 더 빨리 실행할 수 있는지 조언해 주시면 감사하겠습니다!

잘 부탁드립니다.

쿼리에는 다음 세 개의 열이 포함됩니다.user_id,created_at그리고.value.

테이블에는 인덱스가 몇 개 있지만 인덱스에 포함된 인덱스는 없습니다.value기둥.설명은 MySQL이 다음 명령어를 사용하고 있음을 나타냅니다.(user_id, updated_at)일치하는 행을 필터링하지만 완전한 결과를 생성하기 위해 테이블을 스캔하여 값을 추출합니다.value일치하는 행에 사용할 열입니다.

인덱스를 생성하는 경우(user_id, created_at, value)커버링 지표로 사용할 수 있습니다...where 절과 일치하여 검색하다value를 참조해 주세요.MySQL은 더 이상 2200만 행 테이블을 터치할 필요가 없습니다.


또, 당신의GROUP BY틀렸습니다.일 년 중 각 요일의 값을 계산하거나 합산해야 합니다.이 경우 다음과 같이 해야 합니다.

SELECT UNIX_TIMESTAMP(CAST(created_at AS DATE)) * 1000, SUM(values)
FROM t
WHERE ...
GROUP BY CAST(created_at AS DATE)
ORDER BY CAST(created_at AS DATE)

언급URL : https://stackoverflow.com/questions/68033972/why-does-mysql-query-get-slow-when-i-add-a-column-to-return

반응형