source

Larabel의 "soft_delete"는 MySQL에 인덱스가 필요합니까?

manysource 2022. 10. 15. 09:59

Larabel의 "soft_delete"는 MySQL에 인덱스가 필요합니까?

4.는 mysql)에서 를 사용하는에 larabel 4.2('데이터베이스는 mysql')가 있습니다.WHERE deleted_at IS NULL에 대한 인덱스가 없습니다.deleted_at.

  • ( ( maybe ( ( ( ( ( ( ( ( ( ( ( IS NULL로 하지 ).
  • deleted_at 열? 열?

는 soft_delete인가요?deleted_at"MySQL" "MySQL" "MySQL" "MySQL"?

설명: Laravel은 타임 스탬프를deleted_at부울 값이 아닌 레코드가 소프트 삭제되었음을 나타내는 컬럼입니다.

[ ] deleted_at는 좋은 지표 후보가 아닙니다.이 코멘트보다 더 잘 설명하도록 하겠습니다: 인덱스는 상대적으로 카디널리티가 높을 때만 유용합니다.카디널리티는 데이터 세트의 인덱스 고유성을 나타내는 숫자입니다. 총 를 총 레코드로 입니다.

예를 들어 프라이머리 키의 카디널리티는 1입니다.모든 레코드에는 프라이머리 키에 대한 고유한 값이 포함되어 있습니다.또한 1은 가장 높은 수치입니다.'100%'라고 보시면 됩니다.

그러나 deleted_at과 같은 열에는 이러한 값이 없습니다.Laravel은 deleted_at에서 null 여부를 확인합니다.즉, 두 가지 값이 있을 수 있습니다.두 개의 값이 포함된 열은 카디널리티가 매우 낮으며 레코드 수가 증가할수록 감소합니다.

이러한 열을 인덱싱할 수 있지만 도움이 되지 않습니다.앞으로 일어날 일은 그것이 상황을 느리게 하고 공간을 차지할 수 있다는 것이다.

TL;DR: 아니요, 이 열을 인덱싱할 필요는 없습니다. 인덱스는 성능에 아무런 영향을 미치지 않습니다.

위의 by @N.B.가 왜 이렇게 많은 업보트를 가지고 있는지 모르겠지만, 제 문맥에서는 이것이 완전히 잘못된 것이라고 생각합니다.

일부 키 테이블의 deleted_at 타임스탬프에 인덱스를 추가하고 32초에서 5.4ms 미만으로 떨어진 쿼리를 즐겼습니다.앱의 성질에 따라 달라집니다.

이 시나리오에서는 소프트 삭제가 있는 테이블이 3개 있고, 간단한 조인(모두 인덱스 포함)이 있습니다만, Laravel의 소프트 삭제 처리의 디폴트 특성으로 인해 쿼리에 문제가 있었습니다.

기록 수치가 상승할 때 앱이 질식할 수 있도록 이러한 열을 인덱싱할 것을 강력히 권장합니다.

이행 전. 인덱스 1 인덱스2 인덱스3 이행 후. 5.4ms

단답:아마도요.

장황한 답변:

에 다른 값이 거의 없는 경우deleted_at은 MySQL을 INDEX(deleted_at).

deleted_at, 은 , MySQL을 INDEX(deleted_at).

(지금까지) 대부분의 논의는 이 단일 열 지수의 카디널리티를 고려하지 않았다.

주의: 이것은 등의 2-값 플래그와는 다릅니다.그런 것에 대해 한 줄의 지수를 두는 것은 소용이 없다.

자세한 설명 (MySQL 관점)

https://laravel.com/docs/5.2/eloquent#soft-deleting에 기재되어 있습니다.

이제 모델에서 삭제 메서드를 호출하면 deleted_at 열이 현재 날짜 및 시간으로 설정됩니다.또한 소프트 삭제를 사용하는 모델을 쿼리할 때 소프트 삭제 모델은 모든 쿼리 결과에서 자동으로 제외됩니다.

이를 통해 테이블 정의에서 이것이 발생하고 있다고 생각합니다.

deleted_at  DATETIME  NULL  -- (or TIMESTAMP NULL)

그 은 ( 암묵적으로)됩니다.NULL.

케이스 1: 새 행이 많이 생성되었지만 아직 '삭제'되지 않았습니다. ★★★★★★★★★★★★★★★★★.deleted_at값은 다음과 같습니다.NULL는 Optimizer를 INDEX(deleted_at)도움이 안 될 것 같아서요실제로 지수를 사용하는 것은 전체 지수와 데이터를 검토하는 데 더 많은 비용이 들기 때문에 해가 될 수 있습니다.지수를 무시하고 단순히 모든 행이 다음 행에 대한 후보라고 가정하는 것이 더 저렴할 것이다.SELECTed.

케이스 2: 몇 개의 행(많은 행 중)이 삭제되었습니다., 이제deleted_at을 사용법을 사용하다라라벨이 신경 쓰는 건IS NULL »IS NOT NULLMySQL 중 my중중 my my my my my 。 시험은 데데근 but but but but의 것이기 때문에IS NULL그리고 대부분의 행은 정지되어 있습니다.NULLOptimizer (최적화기) 케이스 1 (Case 1)

케이스 3: 아직 액티브한 행보다 훨씬 많은 행이 소프트 삭제되어 있습니다.하기 때문에 .IS NULL.

케이스 2와 케이스 3 사이에는 정확한 컷오프가 없습니다.20%는 편리한 경험칙입니다.

자, 실행의 관점에서 보자.

INDEX(deleted_at) used에 deleted_at IS NULL:

  1. 행의 를 Index BTree로 합니다.NULL.
  2. ★★★까지 IS NULLdiscloss.disclosed 입니다.
  3. 일치하는 각 행에 대해 데이터 BTree에 손을 뻗어 행을 가져옵니다.

INDEX(deleted_at)

  1. 데이터 BTree 스캔(또는 다른 인덱스 사용)
  2. 데이터 행에 대해deleted_at IS NULL이 이외의 경우는, 그 행을 필터링 합니다.

복합 인덱스:

"복합"(복수열) 지수가 다음과 같이 시작하는 것이 매우 유익할 수 있습니다.deleted_at. 예:

INDEX(deleted_at, foo)

WHERE deleted_at IS NULL
  AND foo BETWEEN 111 AND 222

이것은 테이블의 몇 퍼센트에 관계없이 인덱스를 효과적으로 사용할 가능성이 매우 높습니다.

  1. 첫 번째 행의 Index BTree 드릴다운NULL그리고.foo >= 111.
  2. 검색 기간IS NULL또는foo <= 222에러가 발생.
  3. 일치하는 각 행에 대해 데이터 BTree에 손을 뻗어 행을 가져옵니다.

주의해 주세요.INDEX,NULL한다.NULLs다른 값보다 먼저 저장됩니다.)

언급URL : https://stackoverflow.com/questions/26525068/does-laravels-soft-delete-need-index-on-mysql