source

MariaDB에서 동일한 쿼리를 애플리케이션에서 Sequitize를 통해 실행할 때 mysql 클라이언트 또는 CLI에서 직접 실행할 때보다 시간이 더 오래 걸리는 이유는 무엇입니까?

nicesource 2023. 6. 8. 19:53
반응형

MariaDB에서 동일한 쿼리를 애플리케이션에서 Sequitize를 통해 실행할 때 mysql 클라이언트 또는 CLI에서 직접 실행할 때보다 시간이 더 오래 걸리는 이유는 무엇입니까?

다음 MariaDB 스키마의 경우:

meta_meta_version

  • id(int)
  • namespace_id(int)
  • 버전(varchar(10))
  • 스키마(긴 텍스트)
  • 주석(중간 텍스트)
  • created_at(날짜 시간)

메타의

  • id (int) [PK]
  • meta_id(int)
  • version_num (int)
  • meta_schema_version_id(int) - [FK to meta_schema_version]
  • 태그(varchar(30))
  • tag_value(varchar(100))
  • 메타(긴 텍스트)
  • 주석(중간 텍스트)
  • is_messages(1)
  • update_at(날짜 시간)
  • updated_by(varchar(100))

메타 테이블의 인덱스는 다음과 같습니다.

  • id - 기본 키 - BTREE - 고유
  • meta_schema_version_id - 외부 키 - BTREE - 고유하지 않음
  • idx_config_id - BTREE - 고유하지 않음

메타 테이블에는 백만 개 이상의 레코드가 있습니다.

다음과 같은 페이지 목록을 가져오기 위해 Sequetize를 사용하고 있습니다.

metas = await this.meta.findAndCountAll({
                attributes: ['id', 'tag', 'tagValue', ...versionAttribute],
                include: [
                  {
                    model: MetaSchemaVersion,
                    attributes: ['version'],
                  },
                ],
                where: {
                  metaSchemaVersionId: schemaVersion.id,
                  isDeleted: {
                    [Op.eq]: 0,
                  },
                },
                limit,
                offset,
              });

Sequitize는 위 기능에 해당하는 쿼리 2개를 기록합니다. 쿼리 1:

SELECT  count(*) AS `count`
    FROM  `meta` AS `Meta`
    WHERE  `Meta`.`meta_schema_version_id` = 1
      AND  `Meta`.`is_deleted` = 0 

쿼리 2:

SELECT  `id`, `tag`, `tag_value` AS `tagValue`,
        `comment`, `updated_at` AS `updatedAt`,
        `updated_by` AS `updatedBy`,
        `meta_schema_version_id` AS `metaSchemaVersionId`,
        `meta`
    FROM  `meta` AS `Meta`
    WHERE  `Meta`.`meta_schema_version_id` = 1
      AND  `Meta`.`is_deleted` = 0
    LIMIT  0, 10 

long_query_time이 0.0001로 매우 낮은 느린 쿼리 로그를 사용하도록 설정했습니다.

느린 쿼리 로그의 쿼리 시간은 다음과 같습니다.

  • 쿼리 1:00:00:00.612878
  • 쿼리 2:00:00:00.894041

CLI에서 직접 실행할 때 동일한 쿼리가 두 쿼리 모두에 대해 쿼리 시간을 ~00:00.0005로 표시합니다.

Sequetize ORM을 통해 CLI에서 직접 실행할 때와 Sequetize ORM을 통해 실행할 때 쿼리 시간이 그렇게 큰 차이가 나는 이유는 무엇입니까?

느린 쿼리에서 SHOW PROFILE은 다음과 같은 응답을 제공합니다.

[
  { Status: 'Starting', Duration: '0.000026' },
  { Status: 'Opening tables', Duration: '0.000025' },
  { Status: 'System lock', Duration: '0.000003' },
  { Status: 'table lock', Duration: '0.000004' },
  { Status: 'Opening tables', Duration: '0.000002' },
  { Status: 'After opening tables', Duration: '0.000100' },
  { Status: 'closing tables', Duration: '0.000003' },
  { Status: 'Unlocking tables', Duration: '0.000003' },
  { Status: 'closing tables', Duration: '0.000073' },
  { Status: 'checking permissions', Duration: '0.000005' },
  { Status: 'Opening tables', Duration: '0.000013' },
  { Status: 'After opening tables', Duration: '0.000004' },
  { Status: 'System lock', Duration: '0.000004' },
  { Status: 'table lock', Duration: '0.000006' },
  { Status: 'init', Duration: '0.000033' },
  { Status: 'Optimizing', Duration: '0.000018' },
  { Status: 'Statistics', Duration: '0.000074' },
  { Status: 'Preparing', Duration: '0.000024' },
  { Status: 'Executing', Duration: '0.000002' },
  { Status: 'Sending data', Duration: '0.880704' },
  { Status: 'End of update loop', Duration: '0.000016' },
  { Status: 'Query end', Duration: '0.000003' },
  { Status: 'Commit', Duration: '0.000005' },
  { Status: 'closing tables', Duration: '0.000003' },
  { Status: 'Unlocking tables', Duration: '0.000002' },
  { Status: 'closing tables', Duration: '0.000043' },
  { Status: 'Starting cleanup', Duration: '0.000003' },
  { Status: 'Freeing items', Duration: '0.000010' },
  { Status: 'Updating status', Duration: '0.000015' },
  { Status: 'Logging slow query', Duration: '0.000006' },
  { Status: 'Opening tables', Duration: '0.000016' },
  { Status: 'System lock', Duration: '0.000002' },
  { Status: 'table lock', Duration: '0.000003' },
  { Status: 'Opening tables', Duration: '0.000002' },
  { Status: 'After opening tables', Duration: '0.000059' },
  { Status: 'closing tables', Duration: '0.000002' },
  { Status: 'Unlocking tables', Duration: '0.000002' },
  { Status: 'closing tables', Duration: '0.000005' },
  { Status: 'Reset for next command', Duration: '0.000238' }
]

업데이트 1: 제 원래 게시물에 언급된 쿼리가 잘못되었습니다.SQL 쿼리를 복사할 때 ORM 코드에서 조인 부분을 코멘트했습니다.올바른 쿼리는 다음과 같습니다.

쿼리 1:

SELECT count(Meta.id) AS count FROM meta AS Meta LEFT OUTER JOIN meta_schema_version AS metaSchemaVersion ON Meta.meta_schema_version_id = metaSchemaVersion.id WHERE Meta.meta_schema_version_id = 1 AND Meta.is_deleted = 0;

쿼리 2:

SELECT Meta.id, Meta.tag, Meta.tag_value AS tagValue, Meta.comment, Meta.updated_at AS updatedAt, Meta.updated_by AS updatedBy, Meta.meta_schema_version_id AS metaSchemaVersionId, Meta.meta, metaSchemaVersion.id AS metaSchemaVersion.id, metaSchemaVersion.version AS metaSchemaVersion.version FROM meta AS Meta LEFT OUTER JOIN meta_schema_version AS metaSchemaVersion ON Meta.meta_schema_version_id = metaSchemaVersion.id WHERE Meta.meta_schema_version_id = 1 AND Meta.is_deleted = 0 LIMIT 0, 20;

이것은 도움이 될 수 있습니다.Meta두 쿼리 모두에 대해:

INDEX(meta_schema_version_id, is_deleted)   -- (the column order does not matter)

그러나, a.LIMIT무턱내지 않고ORDER BY무슨 일이 일어나든 당신에게 줄 것입니다추가하는 경우ORDER BY최적의 상태를 재분석해야 합니다.INDEX

(저는 매우 부정적인 의견을 가지고 있습니다.Profile거의 모든 시간이 암호화된 "데이터 전송"에서 발생합니다.이것은 일반적입니다.)

CLI에서 직접 실행할 때 동일한 쿼리

그것에 대한 두 가지 가능한 이유가 있습니다.다음과 같이 쿼리를 실행할 것을 권장합니다.

SELECT SQL_NO_CACHE ...`
  • 이렇게 하면 쿼리와 쿼리 결과가 캐시되는 "쿼리 캐시"를 피할 수 있습니다. 두 번째 실행은 기본적으로 00:00:00.0005와 같이 즉시 실행되기 때문입니다.
  • 또는... 첫 번째 실행에서는 디스크에서 많은 데이터를 가져와 RAM에 캐시된 데이터 때문에 두 번째 실행 속도가 훨씬 빨라졌을 수 있습니다.

플래그를 추가하고 쿼리를 두 번 실행한 다음 두 번째 타이밍을 잡습니다.

저는 제 로컬 개발 기계의 앱 서버에서 요청을 하고 있습니다.

네트워크 지연 시간(오버헤드)을 테스트하는 한 가지 방법은 사소한 시간을 측정하는 것입니다.SELECT 1;질의하다

쿼리 1은 전체 테이블을 검색해야 합니다.내 색인을 사용하면 색인의 일부를 검색합니다.

쿼리 2, 다음을 제외합니다.ORDER BY테이블이 일치하는 10개의 행을 찾을 때까지 테이블을 스캔합니다.WHERE

언급URL : https://stackoverflow.com/questions/73496328/why-is-the-same-query-on-mariadb-taking-more-time-when-run-via-sequelize-from-th

반응형