programing

가입은 게으른 사람들을 위한 건가요?

prostudy 2022. 7. 27. 21:43
반응형

가입은 게으른 사람들을 위한 건가요?

최근 JOIN(SQL)은 무용지물이라고 주장하는 다른 개발자와 논의를 했습니다.이것은 기술적으로 사실이지만, Join을 사용하는 것은 코드(C# 또는 Java)에서 여러 요청 및 링크 테이블을 만드는 것보다 효율적이지 않다고 덧붙였습니다.

그에게 가입은 실적에 신경 쓰지 않는 게으른 사람들을 위한 것이다.정말이에요?조인 사용을 피해야 할까요?

아니요, 우리는 그렇게 엄청나게 잘못된 의견을 가진 개발자들을 피해야 합니다.

DB 라운드 트립을 피할 수 있고 DB가 인덱스를 사용하여 조인 작업을 수행할 수 있기 때문에 대부분의 경우 데이터베이스 조인 속도는 클라이언트를 통해 수행되는 것보다 몇 배나 빠릅니다.

즉, 올바르게 사용되는 Join이 동등한 클라이언트 측 조작보다 느릴 수 있는 단일 시나리오가 상상조차 할 수 없습니다.

편집: 커스텀 클라이언트 코드가 간단한 DB 가입보다 더 효율적으로 작업을 수행할 수 있는 드문 경우가 있습니다(메리트론 코멘트 참조).하지만 이것은 매우 예외적이다.

당신의 동료는 no-sql 문서 데이터베이스나 키 밸류 스토어를 사용하는 것이 좋을 것 같습니다.그 자체는 매우 좋은 도구이며 많은 문제에 적합합니다.

그러나 관계형 데이터베이스는 집합 작업에 크게 최적화되어 있습니다.조인(join)을 기반으로 데이터를 조회하는 방법은 여러 가지가 있으며, 많은 라운드 트립보다 훨씬 효율적입니다.여기서 RDBMs의 용도가 나옵니다.nosql 스토어에서도 동일한 작업을 수행할 수 있지만 쿼리 성격에 따라 개별 구조를 구축하게 되는 경우가 많습니다.

요컨대, 나는 동의하지 않는다.RDBMS에서는 조인은 기본입니다.사용하지 않으면 RDBMS로 사용하지 않습니다.

글쎄, 일반적인 경우에서 그는 틀렸어.

데이터베이스는 옵티마이저 힌트, 테이블 인덱스, 외부 키 관계 및 기타 데이터베이스 벤더 고유 정보를 통해 다양한 방법을 사용하여 최적화할 수 있습니다.

아니, 안 돼.

데이터베이스는 데이터 세트를 조작하도록 특별히 설계되었습니다(분명히...).그러므로 그들은 이것을 하는데 매우 효율적입니다.기본적으로 자신의 코드에 수동으로 참여함으로써, 그는 그 일에 맞게 특별히 설계된 어떤 역할을 이어받으려고 시도하고 있습니다.그의 코드가 데이터베이스에 있는 것만큼 효율적일 가능성은 매우 희박합니다.

참고로 조인 없이 데이터베이스를 사용하는 이유는 무엇입니까?그냥 텍스트 파일을 사용하는 게 나을 거예요

게으름뱅이가 코드를 적게 쓰는 사람으로 정의된다면 저도 동의합니다.게으름뱅이가 도구에 자신이 잘하는 일을 시키고 싶은 사람으로 정의된다면, 저는 동의합니다.그래서 만약 그가 단지 래리 월(훌륭한 프로그래머의 특성에 관해서)에 동의해요.

음, join은 관계형 데이터베이스가 테이블을 서로 연관짓는 방법입니다.나는 그가 무슨 말을 하려는지 잘 모르겠다.

데이터베이스에 여러 개의 콜을 발신하는 것이 어떻게 한 번의 콜보다 효율적일 수 있을까요?또한 SQL 엔진은 이러한 작업에 최적화되어 있습니다.

아마도 당신의 동료가 SQL을 배우는데 너무 게을러서 일지도 몰라요.

그래, 그래야지.

그리고 성능상 C# 대신 C++를 사용해야 합니다.C#은 게으른 사람들을 위한 것이다.

아니, 아니, 아니.성능상 C++ 대신 C를 사용해야 합니다.C++는 게으른 사람들을 위한 것이다.

아니, 아니, 아니.성능 때문에 C 대신 어셈블리를 사용해야 합니다.C는 게으른 사람들을 위한 것이다.

네, 농담입니다.조인 없이 더 빠른 프로그램을 만들 수 있고 조인 없이 더 적은 메모리를 사용하여 프로그램을 만들 수 있습니다.그러나 대부분의 경우 CPU의 시간과 메모리보다 개발 시간이 더 중요합니다.작은 공연을 포기하고 인생을 즐기세요.작은 성과에 시간을 낭비하지 마세요.그리고 그에게 "집에서 사무실까지 직진하는 게 어때?"라고 말해라.

"이것은 기술적인 사실입니다." 마찬가지로 SQL 데이터베이스도 쓸모가 없습니다. CSV 파일 묶음을 사용하여 코드와 관련지어 동일한 결과를 얻을 수 있는데 SQL 데이터베이스를 사용하는 것이 무슨 의미가 있습니까?헉, 어떤 추상화든 게으른 사람들을 위한 것입니다. 하드웨어에서 기계 코드로 프로그래밍하는 것으로 돌아가 봅시다!;)

또한 RDBMS는 JOIN을 빠르게 하기 위해 고도로 최적화되어 있다는 가장 복잡한 경우를 제외하고는 그의 주장은 사실이 아닙니다.관계형 데이터베이스 관리 시스템, 맞죠?

지난번 근무한 회사에서도 SQL Join을 사용하지 않았습니다.대신 이 작업을 수평으로 확장하도록 설계된 애플리케이션 계층으로 이동했습니다.이 설계의 이유는 데이터베이스 계층에서의 작업을 피하기 위해서입니다.일반적으로 병목현상이 되는 것은 데이터베이스입니다.데이터베이스보다 애플리케이션 계층을 복제하는 것이 더 쉽습니다.다른 이유가 있을 수도 있어요하지만 이게 내가 지금 기억할 수 있는 거야.

예. 애플리케이션 계층에서 이루어지는 조인은 데이터베이스에 의한 조인에 비해 비효율적이라는 데 동의합니다.네트워크 통신도 확대됩니다.

SQL 가입을 회피하는 것에 대해서는 강경한 입장을 취하고 있지 않습니다.

가입하지 않고 주문 항목을 주문과 어떻게 관련지을 수 있습니까?이것이 관계형 데이터베이스 관리 시스템의 전체 포인트입니다.조인하지 않으면 관계형 데이터가 없으므로 텍스트 파일을 사용하여 데이터를 처리하는 것이 좋습니다.

개념을 이해하지 못하는 것 같아서 쓸모없는 것처럼 보이게 하려고 하는 것 같아.그는 엑셀이 데이터베이스 애플리케이션이라고 생각하는 것과 같은 타입이다.바보같이 때리고 데이터베이스에 대해 더 읽으라고 해C#을 통해 여러 개의 접속을 확립하고 데이터를 풀하여 Marge하는 것은 잘못된 방법입니다.

"SQL에 가입하는 것은 쓸모가 없다"는 문장의 논리를 이해할 수 없습니다.데이터를 작업하기 전에 필터링하고 제한하는 것이 유용한가요?다른 응답자분들도 이렇게 말씀하셨듯이, 데이터베이스 엔진이 잘하는 것이어야 합니다.

게으른 프로그래머라면 익숙한 기술을 고수하고 비기술적인 이유로 다른 가능성을 회피할 수도 있습니다.

결정은 당신에게 맡기겠어요.

예를 들어 청구서 레코드가 있는 표와 청구서 라인 항목 레코드가 있는 관련 표가 있습니다.클라이언트 유사 코드를 검토합니다.

for each (invoice in invoices)
    let invoiceLines = FindLinesFor(invoice)
...

각각 10줄씩 10줄씩 10줄씩의 송장이 있는 경우, 이 코드는 100,000번 테이블에서 10줄씩을 검색합니다.테이블 크기가 커지면 선택 작업의 수가 증가하고 각 선택 작업의 비용이 증가합니다.

컴퓨터는 속도가 빠르기 때문에 수천 개 이하의 레코드가 있는 경우 두 접근 방식 간의 성능 차이를 알아차리지 못할 수 있습니다.코스트의 증가는 단순한 것이 아니기 때문에, 레코드의 수가 증가하면(예를 들면 수백만 개까지), 그 차이를 깨닫기 시작하고, 데이터 세트의 사이즈가 커지면, 그 차이는 견딜 수 없게 됩니다.

그러나 조인에서는 테이블의 인덱스를 사용하고 두 데이터 세트를 병합합니다.즉, 두 번째 테이블을 N번 랜덤으로 액세스하는 것이 아니라 실제로 한 번 스캔하는 것입니다.외부 키가 정의되어 있는 경우 데이터베이스에는 이미 내부적으로 저장된 관련 레코드 간의 링크가 있습니다.

직접 한다고 상상해 보세요.학생의 알파벳순 리스트와 모든 학생의 성적 보고서가 포함된 노트북(클래스당 1페이지)이 있습니다.노트북은 학생 이름 순으로 목록과 같은 순서로 정렬됩니다.어떻게 진행하시겠습니까?

  1. 목록에서 이름을 읽습니다.
  2. 노트북을 엽니다.
  3. 학생의 이름을 찾습니다.
  4. 학생의 성적을 읽으면서 다음 학생이나 마지막 페이지에 도달할 때까지 페이지를 넘깁니다.
  5. 노트북을 닫습니다.
  6. 따라하다.

또는 다음 중 하나를 선택합니다.

  1. 노트북의 첫 페이지를 엽니다.
  2. 목록에서 이름을 읽습니다.
  3. 노트북에서 해당 이름의 학점을 읽습니다.
  4. 끝까지 2-3단계를 반복합니다.
  5. 노트북을 닫습니다.

" 잘 쓸 수 있어"의 전형적인 사례처럼 들리네요.즉, 그는 (SQL에 많은 조인을 쓰는 것은) 귀찮은 일이라고 생각하면서 "그것을 더 잘 쓰고 더 나은 성능을 얻을 수 있을 것"이라고 말하고 있습니다.a) Oracle 또는 SQL Server 최적화 코드에 정통한 일반 사용자보다 똑똑하고 b) 교육 수준이 높은지 물어봐야 합니다.아마 아닐 거야

그는 틀림없이 틀렸다.C#이나 Java와 같은 언어에서 데이터를 조작하는 데는 확실한 장점이 있지만 SQL 자체의 특성으로 인해 조인 속도가 데이터베이스에서 가장 빠릅니다.

SQL은 데이터에 대한 통계를 지속적으로 상세하게 제공하며 인덱스를 올바르게 생성하면 200만 개 중 하나의 레코드를 매우 빠르게 찾을 수 있습니다.게다가 데이터베이스 레벨에서 제대로 할 수 있는데 왜 모든 데이터를 C#에 끌어다 놓고 참여하려고 합니까?

C#의 장점은 무언가를 반복해야 할 때 발휘됩니다.각 행에 대해 몇 가지 기능을 수행해야 하는 경우 C# 내에서 수행하는 것이 더 빠를 수 있습니다. 그렇지 않으면 데이터 결합이 DB에서 최적화됩니다.

쿼리를 분해하고 코드 조인을 하는 것이 더 빠를 경우라고 하겠습니다.단, MySQL의 특정 버전만 사용할 수 있었습니다.그 외에는 데이터베이스가 더 빨라질 수 있습니다(쿼리를 최적화해야 할 수도 있지만 여전히 더 빠릅니다).

나는 그가 어떤 데이타베이스에 사용되어야 하는지에 대한 제한된 견해를 가지고 있다고 의심한다.성능을 최대화하는 방법 중 하나는 데이터베이스 전체를 메모리로 읽는 것입니다.이 경우 성능이 향상될 수 있으며 효율성을 위해 메모리의 경우 Join을 수행할 수 있습니다.단, 데이터베이스 IMHO로서 실제로 데이터베이스를 사용하는 것은 아닙니다.

아니요, Join은 애드혹 C#/Java 데이터베이스 코드로 최적화되어 있을 뿐만 아니라 일반적으로 몇 가지 필터링 기술을 적용할 수 있기 때문에 성능이 더욱 향상됩니다.

그는 틀렸습니다. 조인은 유능한 프로그래머들이 사용하는 것입니다.그가 제안한 방법이 더 효율적인 경우가 몇 가지 있을 수 있지만(이 경우 Documant 데이터베이스를 사용하고 있을 가능성이 높지만), 데이터량이 일정하지 않으면 알 수 없습니다.예를 들어 다음 쿼리를 예로 들 수 있습니다.

select t1.field1 
from table1 t1
join table2 t2 
    on t1.id = t2.id
where t1.field2 = 'test'

표 1에 1000만 개의 레코드가 있고 표 2에 100만 개의 레코드가 있다고 가정합니다.표 1의 레코드 중 900만 개가 where 절을 충족한다고 가정합니다.표 2에도 15개만 있다고 가정합니다.이 sql 문을 실행할 수 있습니다.이 sql 문은 인덱스가 올바르게 작성되면 밀리초가 걸리고 15개의 레코드가 1컬럼의 데이터만으로 네트워크를 통해 반환됩니다.또는 1000만 개의 레코드와 2개의 데이터 열을 함께 전송하고 100만 개의 레코드와 1개의 데이터 열을 별도로 네트워크를 통해 전송하여 웹 서버에서 결합할 수 있습니다.

또는 데이터베이스의 전체 내용을 항상 웹 서버에 보관할 수도 있습니다. 계속 변화하는 데이터 및 데이터의 양이 너무 많으면 이는 매우 어리석은 일입니다.관계형 데이터베이스의 품질이 필요하지 않은 경우 사용하지 마십시오.하지만 만약 그렇다면, 올바르게 사용하세요.

저는 소프트웨어 개발자로 일하는 동안 이 주장을 꽤 자주 들었습니다.거의 매번 그 주장을 하는 사람은 관계형 데이터베이스 시스템, 그 작동 방식 및 그러한 시스템의 사용 방법에 대해 잘 알지 못했습니다.

네, 잘못 사용하면 조인(join)은 무용지물이거나 위험합니다.그러나 올바른 방법으로 사용하면 데이터베이스 구현이 최적화를 수행하고 개발자가 올바른 결과를 가장 효율적으로 검색할 수 있도록 지원할 수 있습니다.

이 점을 잊지 마십시오.JOIN각 데이터가 서로 관련지어질 것으로 예상되는 방법을 데이터베이스에 전달하여 원하는 작업에 대한 많은 정보를 데이터베이스에 제공하므로 사용자의 요구에 더 잘 부합할 수 있습니다.

그래서 대답은 확실히 '아니요'입니다.JOINS전혀 쓸모없는 게 아니야!

이는 응용 프로그램에서 자주 사용되지 않는 경우(조인의 모든 테이블 행이 쿼리에 의해 반환되는 경우)에만 "기술적으로 참"입니다.대부분의 쿼리에서는 각 테이블 행의 극히 일부만 반환됩니다.데이터베이스 엔진은 인덱스에 저장된 값을 사용할 수 있기 때문에 종종 인덱스를 사용하여 불필요한 행을 제거합니다. 경우에 따라서는 실제 행을 읽지 않아도 인덱스에 저장된 값을 사용할 수 있습니다.데이터베이스 엔진 자체는 C, C++ 등으로 작성되며 적어도 개발자가 작성한 코드만큼 효율적입니다.

내가 심각하게 오해한 게 아니라면, 질문의 논리는 매우 결함이 있다.

각 A에 대해 B에 20개의 행이 있는 경우, A에 1000개의 행은 B에 20k개의 행을 의미합니다.매핑을 포함하는 20k 행을 가진 다대 테이블 "AB"가 존재하지 않는 한 B에는 100개의 행만 존재할 수 없습니다.

따라서 100개의 B행 중 어떤 20개가 각 A행에 매핑되는지에 대한 모든 정보를 얻으려면 AB도 참조하십시오.다음 중 하나가 됩니다.

  • 100, 1000 및 20k 행과 클라이언트 JOIN의 3가지 결과 세트
  • 20k행의 단일 JOINED A-AB-B 결과 세트

따라서 클라이언트의 "JOIN"은 데이터를 검토할 때 모든 가치를 추가합니다.그게 나쁜 생각이 아니라는 건 아니야.하나의 개체를 데이터베이스에서 가져오는 경우 개별 결과 세트로 세분하는 것이 더 합리적일 수 있습니다.리포트 타입의 콜의 경우는, 거의 항상 하나로 정리합니다.

어떤 경우든, 이 정도 크기의 교차 결합은 거의 쓸모가 없다고 말하고 싶습니다.그것은 나쁜 예다.

어디선가 가입해야 하는데 그게 RDBMS의 장점이에요.더 잘할 수 있다고 생각하는 클라이언트 코드 원숭이와 일하고 싶지 않아요.

심사숙고:

클라이언트에 가입하려면 DataTables 등의 영속적인 오브젝트가 필요합니다(.net의 경우).평탄한 결과 세트가 1개 있는 경우 DataReader와 같은 가벼운 것을 통해 소비할 수 있습니다.대용량 = 데이터베이스 JOIN을 피하는 데 사용되는 클라이언트 리소스입니다.

언급URL : https://stackoverflow.com/questions/5595418/joins-are-for-lazy-people

반응형