>  Q&A  >  본문

행 수가 매우 다른데도 쿼리가 데이터를 가져오는 데 동일한 시간이 걸리는 이유는 무엇입니까?

내 VISITS 테이블에는 다음과 같은 29,938,766개의 행이 있습니다

USER_ID (INT) VISITED_IN(DATETIME)
65 2020-08-26 07:57:43
1182 2019-03-15 02:46:48
1564 2015-07-04 10:59:44
73 2021-03-18 00:25:08
3791 2017-10-17 12:22:45
51 2022-05-02 19:11:09
917 2017-11-20 15:32:06
3 2019-12-29 15:15:51
51 2015-02-08 17:48:30
1531 2020-08-05 08:44:55
잠깐... 잠깐...

이 쿼리를 실행하면 17~20초가 걸리고 63,514가 반환됩니다(사용자 방문 횟수는 63,514회)

으아아아

이 쿼리를 실행하면 17~20초가 걸리고 193이 반환됩니다(사용자 방문 횟수는 193회입니다)

으아아아

문제는 사용자의 방문 횟수가 3, 50, 70 또는 1,000,000회에 불과하더라도 29,938,766개의 행을 쿼리하는 데 항상 17-20초가 걸린다는 것입니다.

모든 행을 반복하기 때문에 문제가 있는 것 같은데요?

두 번째 쿼리는 첫 번째 쿼리보다 빨라야 합니다. 행 수에 따라 다릅니다. 그러나 두 쿼리 모두 동일한 시간이 걸립니다!

이 문제를 방지하기 위한 어떤 제안이 있습니까?


테이블 구조


업데이트: 새로운 제안 시나리오는 다음과 같습니다.

사용자가 자신이나 다른 사람의 프로필에 접속하면 프로필 방문 횟수를 볼 수 있고 이 방법으로 방문 횟수를 필터링할 수 있습니다

으아아아

또한 이 명령을 매일 실행하는 반복 이벤트를 만들겠습니다.

으아아아

또한 VISITS 테이블에 새 행을 추가할 때 VISITS 열을 증가시키도록 하겠습니다.

SELECT COUNT(*) FROM VISITS WHERE USER_ID = 917

P粉795311321P粉795311321205일 전418

모든 응답(1)나는 대답할 것이다

  • P粉381463780

    P粉3814637802024-03-29 11:23:48

    으아아아

    당신이 언급한 모든 SELECTs 속도가 빨라질 것입니다. 그들은 인덱스의 큰 덩어리를 스캔해야 하며 "전체 테이블을 스캔"할 필요는 없습니다.

    DELETE `INDEX(visited_in)가 필요합니다. 하지만 자주 실행하지 않으면 문제가 발생할 수 있습니다. 수천 개의 행을 한 번에 삭제하는 것은 문제가 될 수 있기 때문입니다. 적어도 한 시간에 한 번씩 삭제 작업을 실행하는 것이 좋습니다.

    테이블이 매우 큰 경우에는 "시계열" 파티셔닝 사용을 고려하세요. DROP PARTITION를 사용하면 속도가 훨씬 빨라집니다. 파티션

    모든 캐싱 서비스는 오래된 개수를 제공하지만 때로는 더 빠른 경우도 있습니다.

    "누군가 페이지를 열 때마다 데이터베이스에 액세스할 수 있습니다." 그러나 쿼리가 충분히 효율적인 경우에만 가능합니다. 인덱싱을 수행합니다.

    다른 질문에 대한 답변에서 요약 테이블이 작업 속도를 더욱 높이는 방법을 설명했습니다. 그러나 "지난 N일"은 자정부터 자정까지 측정된다고 가정합니다. 현재 검색어는 NOW() - INTERVAL N DAY입니다. 이는 자정보다 구현하기가 더 혼란스럽습니다. '지난 N일'의 의미를 변경하시겠습니까?

    (일부 INDEX 기본 사항...)

    모든 인덱스의 중요한 이유는 특정 열을 기반으로 행을 빠르게 찾는 기능입니다.

    • INDEX은 행에 매핑된 키 목록입니다.
    • UNIQUE INDEXUNIQUE INDEXINDEX에 고유성 제약 조건을 더한 것입니다. 즉, 인덱스의 두 행에 동일한 값이 없다는 의미입니다.
    • Unique PRIMARY KEY는 테이블의 각 행을 고유하게 식별하도록 지정된 고유 인덱스입니다.

    "키"와 "인덱스"는 동의어입니다.

    인덱스(MySQL의 InnoDB 엔진)는 BTree(실제로는 B+Tree, Wikipedia 참조)로 구현됩니다. PK의 경우 나머지 열은 PK 값과 함께 위치합니다. "보조" 키의 경우 BTree의 "값" 부분은 PK 열입니다.

    모든 인덱스에는 하나 이상의 열("복합"이라고 함)이 포함될 수 있습니다.

    INDEX(lastname) 유일한 사람일 가능성은 낮음 INDEX(lastname,firstname) 여전히 고유할 가능성은 없지만 "복합"입니다.

    회신하다
    0
  • 취소회신하다