최근에 JOIN (SQL)이 쓸모 없다고 주장한 다른 개발자와 토론을했습니다. 이것은 기술적으로 사실이지만 조인을 사용하는 것이 코드에서 여러 요청 및 링크 테이블 (C # 또는 Java)을 만드는 것보다 비효율적이라고 덧붙였습니다.
그에게 참여는 성능에 관심이없는 게으른 사람들을위한 것입니다. 이것이 사실입니까? 조인을 사용하지 않아야합니까?
최근에 JOIN (SQL)이 쓸모 없다고 주장한 다른 개발자와 토론을했습니다. 이것은 기술적으로 사실이지만 조인을 사용하는 것이 코드에서 여러 요청 및 링크 테이블 (C # 또는 Java)을 만드는 것보다 비효율적이라고 덧붙였습니다.
그에게 참여는 성능에 관심이없는 게으른 사람들을위한 것입니다. 이것이 사실입니까? 조인을 사용하지 않아야합니까?
답변:
아닙니다. 우리는 그러한 잘못된 의견을 가진 개발자를 피해야합니다.
많은 경우에 데이터베이스 조인은 DB 왕복을 피하고 DB는 인덱스를 사용하여 조인을 수행 할 수 있기 때문에 클라이언트를 통해 수행되는 것보다 몇 배 빠릅니다.
내 머리 꼭대기에서 올바르게 사용 된 조인이 동등한 클라이언트 측 작업보다 느린 단일 시나리오조차 상상조차 할 수 없습니다.
편집 : 사용자 정의 클라이언트 코드가 간단한 DB 조인보다 효율적으로 작업을 수행 할 수있는 드문 경우가 있습니다 (meriton의 의견 참조). 그러나 이것은 예외입니다.
동료가 SQL이없는 문서 데이터베이스 또는 키 값 저장소와 잘 어울리는 것처럼 들립니다. 그 자체로는 매우 훌륭한 도구이며 많은 문제에 적합합니다.
그러나 관계형 데이터베이스는 세트 작업에 최적화되어 있습니다. 많은 왕복 여행보다 훨씬 효율적인 조인을 기반으로 데이터를 쿼리하는 방법에는 여러 가지가 있습니다. 이것이 바로 rdbms의 다재다능 함입니다. nosql 스토어에서도 동일한 결과를 얻을 수 있지만, 종종 각기 다른 쿼리 특성에 적합한 별도의 구조를 구축하게됩니다.
한마디로 : 동의하지 않습니다. RDBMS에서 조인은 기본 입니다. 사용하지 않는 경우 RDBMS로 사용하지 않는 것입니다.
글쎄, 그는 일반적인 경우에 틀렸다.
데이터베이스는 옵티 마이저 힌트, 테이블 인덱스, 외래 키 관계 및 기타 데이터베이스 공급 업체별 정보를 통해 다양한 방법을 사용하여 최적화 할 수 있습니다.
아닙니다.
데이터베이스는 특별히 데이터 세트를 조작하도록 설계되었습니다 (분명히 ....). 따라서이 작업을 수행하는 데 매우 효율적입니다. 그는 본질적으로 자신의 코드에서 수동 조인을 수행함으로써 해당 작업을 위해 특별히 설계된 무언가의 역할을 인수하려고합니다. 그의 코드가 데이터베이스의 코드만큼 효율적일 가능성은 매우 먼 것입니다.
조인없이 따로 데이터베이스 사용의 요점은 무엇입니까? 텍스트 파일 만 사용할 수도 있습니다.
"게으른"이 적은 코드를 작성하려는 사람들로 정의되면 동의합니다. "게으른"이 도구가 자신이 잘하는 일을하도록하려는 사람들로 정의된다면, 나는 동의한다. 그가 단지 Larry Wall (좋은 프로그래머의 속성과 관련하여)에 동의한다면, 나는 그에게 동의합니다.
그렇습니다.
성능 때문에 C # 대신 C ++를 사용해야합니다. C #은 게으른 사람들을위한 것입니다.
아니, 아니. 성능 때문에 C ++ 대신 C를 사용해야합니다. C ++는 게으른 사람들을위한 것입니다.
아니, 아니. 성능 때문에 C 대신 어셈블리를 사용해야합니다. C는 게으른 사람들을위한 것입니다.
네, 농담입니다. 조인없이 더 빠른 프로그램을 만들 수 있으며 조인없이 더 적은 메모리를 사용하여 프로그램을 만들 수 있습니다. 그러나 많은 경우 개발 시간이 CPU 시간 및 메모리보다 중요합니다. 약간의 성능을 포기하고 인생을 즐기십시오. 약간의 성능을 위해 시간을 낭비하지 마십시오. "당신은 왜 당신의 사무실에서 사무실로가는 고속도로를 만들지 않습니까?"
"이것은 기술적으로 사실입니다."-마찬가지로 SQL 데이터베이스도 쓸모가 없습니다. 많은 CSV 파일을 사용하여 코드로 서로 연관 시켜서 동일한 결과를 얻을 수있는 경우 데이터베이스를 사용하는 것이 무엇입니까? 도대체 모든 게으른 사람들을위한 것입니다. 하드웨어에서 바로 기계 코드 프로그래밍으로 돌아가 봅시다! ;)
또한 그의 주장은 가장 복잡한 경우를 제외하고는 모두 사실이 아닙니다. RDBMS는 JOIN을 빠르게 하기 위해 크게 최적화되어 있습니다. 관계형 데이터베이스 관리 시스템?
unnecessary
것 useless
입니다. 조인이 쓸모 없다고 말하는 것은 고려할 필요가있는 기술이 없기 때문에 특허 적으로 사실이 아닙니다. 어쨌든 OP와 RDBMS의 요점에 대한 오해는 드물지 않습니다. stackoverflow.com/q/5575682/47550
내가 일한 마지막 회사는 SQL 조인도 사용하지 않았습니다. 대신에 그들은이 작업을 수평으로 확장하도록 설계된 응용 계층으로 옮겼습니다. 이 설계의 근거는 데이터베이스 계층에서의 작업을 피하는 것입니다. 일반적으로 병목 현상이 발생하는 데이터베이스입니다. 데이터베이스보다 응용 프로그램 계층을 복제하는 것이 더 쉽습니다. 다른 이유가있을 수 있습니다. 그러나 이것은 내가 지금 기억할 수있는 것입니다.
예, 응용 프로그램 계층에서 수행 된 조인은 데이터베이스에서 수행 한 조인에 비해 비효율적입니다. 더 많은 네트워크 통신.
SQL 조인을 피하기 위해 열심히 노력하고 있지는 않습니다.
송장 레코드가있는 테이블과 송장 개별 항목 레코드가있는 관련 테이블을 예로 들어 보겠습니다. 클라이언트 의사 코드를 고려하십시오.
for each (invoice in invoices)
let invoiceLines = FindLinesFor(invoice)
...
10 개의 송장을 가진 10 개의 송장이있는 경우이 코드는 1 백만 표에서 10 개의 송장을 조회하며 10 만 번 수행합니다. 테이블 크기가 증가하면 선택 조작 수가 증가 하고 각 선택 조작 비용이 증가합니다.
컴퓨터가 빠르면 레코드가 수천 개 이하인 경우 두 방법간에 성능 차이를 느끼지 못할 수 있습니다. 비용 증가는 선형적인 것보다 많기 때문에 레코드 수가 증가함에 따라 (예 : 수백만으로) 차이를 느끼기 시작하고 데이터 세트의 크기가 커짐에 따라 그 차이는 용납 될 수 없게됩니다.
그러나 조인. 테이블의 인덱스를 사용하고 두 데이터 세트를 병합합니다. 이것은 두 번째 테이블을 무작위로 N 번 액세스하지 않고 한 번 효과적으로 스캔한다는 것을 의미합니다. 외래 키가 정의되어 있으면 데이터베이스에 이미 내부에 저장된 관련 레코드 간의 링크가 있습니다.
이것을 직접 상상해보십시오. 알파벳순으로 된 학생 목록과 모든 학생의 성적표 (학급당 한 페이지)가있는 노트가 있습니다. 노트북은 목록과 같은 순서로 학생의 이름에 따라 순서대로 정렬됩니다. 어떻게 진행 하시겠습니까?
또는:
그는 확실히 틀렸다. C # 또는 Java와 같은 언어 내에서 데이터 조작에 대한 확실한 전문가가 있지만 SQL 자체의 특성으로 인해 데이터베이스에서 조인이 가장 빠릅니다.
SQL은 데이터에 관한 자세한 통계를 유지하며 인덱스를 올바르게 작성하면 2 백만에서 1 개의 레코드를 매우 빠르게 찾을 수 있습니다. 데이터베이스 수준에서 바로 할 수있을 때 왜 모든 데이터를 C #으로 드래그하여 조인을 수행해야합니까?
C #을 사용하는 전문가는 반복적으로 무언가를해야 할 때 작동합니다. 각 행에 대해 일부 기능을 수행해야하는 경우 C # 내에서 수행하는 것이 더 빠를 수 있습니다. 그렇지 않으면 데이터 조인이 DB에서 최적화됩니다.
어떤 데이터베이스를 사용해야하는지에 대한 제한된 시각을 가지고 있다고 생각합니다. 성능을 최대화하는 한 가지 방법은 전체 데이터베이스를 메모리로 읽는 것입니다. 이 상황에서는 성능이 향상 될 수 있으며 효율성을 위해 메모리 인 경우 조인을 수행 할 수 있습니다. 그러나 이것은 실제로 데이터베이스를 데이터베이스 IMHO로 사용하지 않습니다.
MEMORY
엔진)을 만들 수 있습니다 . 일반적으로 NIH의 심각한 케이스의 기호를 데이터베이스없이 데이터베이스 기능을한다 다시 구현)
그는 틀렸다. 조인은 유능한 프로그래머가 사용하는 것이다. 그의 제안 된 방법이 더 효율적인 몇 가지 경우가있을 수 있으며 (그리고 아마도 Documant 데이터베이스를 사용하고있을 것입니다) 데이터가 부족한 경우 볼 수 없습니다. 예를 들어 다음 쿼리를 사용하십시오.
select t1.field1
from table1 t1
join table2 t2
on t1.id = t2.id
where t1.field2 = 'test'
table1에 천만 개의 레코드가 있고 table2에 백만 개의 레코드가 있다고 가정하십시오. 표 1의 9 백만 개의 레코드가 where 절을 충족한다고 가정하십시오. 이 중 15 개만 table2에 있다고 가정하십시오. 이 sql 문을 실행할 수 있습니다. 제대로 인덱스 된 경우 밀리 초가 걸리고 1 열의 데이터만으로 네트워크에서 15 개의 레코드를 반환합니다. 또는 2 열의 데이터가있는 천만 개의 레코드를 전송하고 네트워크를 통해 하나의 데이터의 열이있는 다른 1 백만 개의 레코드를 별도로 전송하여 웹 서버에서 결합 할 수 있습니다.
또는 지속적으로 변화하는 사소한 양의 데이터와 데이터가있는 경우 웹 서버에 데이터베이스의 전체 내용을 항상 유지할 수 있습니다. 관계형 데이터베이스의 품질이 필요하지 않은 경우 관계형 데이터베이스를 사용하지 마십시오. 그러나 그렇다면 올바르게 사용하십시오.
소프트웨어 개발자로서 경력을 쌓는 동안이 주장을 자주 들었습니다. 언급 될 때마다 관계형 데이터베이스 시스템, 작동 방식 및 시스템 사용 방법에 대한 지식이 많지 않습니다.
예, 잘못 사용하면 하면 조인이 쓸모 없거나 심지어 위험한 것처럼 보입니다. 그러나 올바른 방식으로 사용하면 데이터베이스 구현에서 최적화를 수행하고 개발자가 올바른 결과를 가장 효율적으로 검색 할 수 있도록 도와주는 많은 가능성이 있습니다.
를 사용하는 것을 잊지 마세요 JOIN
당신은 데이터의 조각이 서로 관련이 있으므로에 대한 데이터베이스 더 많은 정보를 제공 할 것으로 예상되는 방식에 대해 데이터베이스에게 무엇을 당신이해야 할 노력하고 따라서는 수 더 나은 당신의 요구에 맞게 제작됩니다.
따라서 대답은 확실합니다 : 아니요, JOINS
전혀 쓸모가 없습니다!
내가 심각하게 오해하지 않는 한, 문제의 논리는 매우 결함이 있습니다
각 A에 대해 B에 20 개의 행이있는 경우 A에 1000 개의 행은 B에 20k 개의 행을 의미합니다. 맵핑이 포함 된 20k 개의 행이있는 많은 테이블 "AB"가 없으면 B에 100 개의 행이있을 수 없습니다. .
따라서 100 개의 B 행 중 20 개가 각 A 행에 매핑되는 모든 정보를 얻으려면 AB도 표로 표시하십시오. 따라서 이것은 다음 중 하나입니다.
따라서 클라이언트의 "JOIN"은 데이터를 검사 할 때 값을 추가합니다. 나쁜 생각이 아닙니다. 데이터베이스에서 하나의 객체를 검색하는 경우 별도의 결과 집합으로 나누는 것이 더 합리적입니다. 보고서 유형 호출의 경우 거의 항상 하나의 형식으로 전개합니다.
어쨌든이 크기의 크로스 조인에는 거의 사용되지 않는다고 말하고 싶습니다. 나쁜 예입니다.
당신은 어딘가에 가입해야하며, 이것이 RDBMS가 잘하는 것입니다. 나는 그들이 더 잘할 수 있다고 생각하는 클라이언트 코드 원숭이와 일하고 싶지 않습니다.
보적:
클라이언트에 참여하려면 DataTables (.net)와 같은 영구 객체가 필요합니다. 하나의 평평한 결과 집합이 있으면 DataReader와 같은 더 가벼운 것을 통해 소비 될 수 있습니다. 대용량 = 데이터베이스 JOIN을 피하는 데 사용되는 많은 클라이언트 자원.