use-the-index-luke 저자 Markus Winand
Markus Winand는 SQL에 대한 통찰력을 제공하고 다양한 시스템이 SQL을 지원하는 방법을 modern-sql.com 에서 보여줍니다. 이전에 그는 use-the-index-luke.com 을 만들었는데, 지금도 활발하게 유지되고 있습니다. Markus는 winand.at 를 통해 강사, 연사 및 컨설턴트로 고용될 수 있습니다.
You can upload a Korean translation of use-the-index-luke.com on your blog
Thank you from the bottom of my heart to author Makus Winand for allowing me.
These are translations that I use for studying by using a papago (google translate)
The translations may not be correct or there may be a typo.
I'd appreciate it if you could point it out in the comments.
use-the-index-luke.com 의 한글번역본을 블로그에 업로드 해도 된다고
허락해주신 Makus Winand 저자님께 진심으로 감사합니다.
이 번역본들은 제가 공부용도로 번역기(papago, google transrate)를 돌려서
번역한 내용들이라 맞지 않거나, 오타가 있을수 있습니다.
댓글로 지적해주시면 감사하겠습니다.
https://use-the-index-luke.com/blog/2013-08/its-not-about-the-star-stupid
select * 는 평판이 좋지 않습니다.
대부분의 사람들은 테이블 정의의 변경으로 인해 탐지하기 어려운 버그가 발생하기 때문이라고 생각합니다.
모든 열을 원하는 순서대로 나열하면 문제가 해결되는 거죠? 네, 하지만 그렇다고 해서 select *의 두번째 문제가 해결되지는 않습니다.
또 다른 문제는 열을 더 요청하면 데이터베이스 작업이 더 많아진다는 것입니다.
놀라운 것은 성능에 미치는 영향이 클 수 있다는 점입니다.
Up to 100x slower when preventing an Index-Only Scan
일반적으로, 요청하는 열이 적을수록 쿼리를 처리할 때 디스크에서 로드해야 하는 데이터가 줄어듭니다. 그러나 이 관계는 비선형적입니다.
테이블에서 선택하는 데는
(1) 인덱스를 사용하여 선택한 행이 저장된 주소를 찾고, (2) 테이블에서 선택한 행을 로드하는 두 가지 단계가 수반되는 경우가 많습니다.
이제 인덱스에 있는 열만 선택하다고 가정해 보십시오. 데이터베이스가 여전히 두 번째 단계를 수행해야 하는 이유는 무엇입니까? 사실 대분의 데이터베이스는 그렇지 않습니다. 인덱스에 저장된 정보만 사용하여 쿼리를 처리할 수 있으므로 인덱스만 검색할 수 있습니다.
하지만 인덱스 전용 검색이 100배 더 빨라야 하는 이유는 무엇입니까?
단순: 이상적인 인덱스는 선택한 행을 서로 옆에 저장합니다. 각 인덱스 페이지에 약 100개의 행이 있는 것은 드문일이 아닙니다.
즉, 대략적인 수치입니다. 인덱스된 열의 크기에 따라 다릅니다. 그럼에도 불구하고 IO 작업 하나가 100개의 행을 가져올 수 있음을 의미합니다.
그러나 테이블 데이터는 그렇게 구성되어 있지 않습니다(예외). 여기서 페이지에는 선택한 행 중 하나와 특정 쿼리에 관심이 없는 다른 많은 행이 포함되어 있는 것이 일반적입니다. 인덱스 전용 검색이 100배 더 빠를 수 있는 이유는 인덱스 액세스가 IO당 100개의 행을 쉽게 제공할 수 있는 반면 테이블 액세스는 일반적으로 IO당 몇 개의 행만 가져올 수 있기 때문입니다.
인덱스에 없는 열을 하나만 선택하면 데이터베이스는 Index-only scan을 수행할 수 없습니다. 만약 당신이 모든 열을 선택한다면, 저는 당신이 담을 알고 있다고 생각합니다.
또한 일부 데이터베이스는 큰 개체를 별도의 위치(예: Oracle 의 LOB)에 저장합니다.
이러한 데이터에 액세스하면 추가 IO도 발생합니다.
Up to 5x slower when bloating server memory footprint
데이터베이스는 결과를 서버의 기본 메모리에 저장하는 것을 피하지만, 로드 후 각행을 전달하고 다시 잊어버리는 대신, 결과를 저장하는 것이 불가피한 경우가 있습니다. 예를 들어 정렬을 수행하려면 모든 행과 선택한 모든 열을 메모리에 저장해야 합니다. 다시 한 번 말하지만, 더 많은 열을 선택할 수록 데이터베이스에 더 많은 메모리가 필요합니다. 최악의 경우 데이터베이스가 디스크에서 외부 정렬을 수행해야 할 수도 있습니다.
그러나 대부분의 데이터베이스는 이러한 종류의 워크로드에 매우 적합합니다.
사용하지 않는 몇 개의 열을 제거하는 것만으로 2배를 정렬하는 속도가 빨라지는 것을 꽤 자주 보았지만 5배를 초과한 경우는 기억나지 않습니다.
그러나, 이것은 단순히 정렬하는 것이 아니라, 해시 조인도 메모리 블롯에 다소 민감합니다.
그게 뭔지 모르시나요? 이 게시글을 읽어주세요.
이것들은 데이터베이스 관점에서 볼 때 가장 중요한 두 가지 문제일 뿐입니다. 네트워크에도 문제가 발생하고 클라이언트도 데이터를 처리해야 하므로 garbage collection에 상당한 부담이 될 수 있습니다.
많은 사람들은 그 별이 나쁜 것이라고 생각합니다.
따라서 ORM이 모든 열을 이름별로 나열하더라도 문제가 없다고 생각합니다. 사실, 범죄는 생각하지 않고 모든 열을 선택하는 것입니다. 대부분은 ORM은 사용자를 대신하여 이러한 범죄를 쉽게 저지릅니다.
우리가 "select * is bad" 라고 말할 때, 우리는 별을 "생각하지 않고 모든 것을 선택"하는 기호로 사용합니다.
이것이 나쁜것입니다. 이름 기억하기 위해 더많은 캐치프라이즈가 필요한 경우 다음과 같이 하십시오:
스타(*)때문이 아니야, 멍청아!
제가 설명하는 방식이 마음에 드신다면, 제 책
*SQL Performance Explained*가 마음에 드실 겁니다.
'use-the-index-luke' 카테고리의 다른 글
D.1 Execution Plan (0) | 2024.02.26 |
---|---|
D.Glossary (0) | 2024.02.22 |
4.Dynamic SQL is Slow (0) | 2024.02.15 |
3.Oracle Cannot Index NULL (0) | 2024.02.12 |
2.Most Selective First (0) | 2024.02.08 |