IT TIP

"in 절"내의 MySQL 항목 수

itqueen 2020. 11. 25. 21:46
반응형

"in 절"내의 MySQL 항목 수


사용자를 정의 할 세 개의 테이블이 있습니다.

USER: user_id (int), username (varchar)
USER_METADATA_FIELD: user_metadata_field_id (int), field_name (varchar)
USER_METADATA: user_metadata_field_id (int), user_id (int), field_value (varchar)

응용 프로그램 내에서 다른 사용자에 대한 특정 액세스 권한이있는 중간 계층 사용자를 만들고 싶습니다. 로그인 한 사용자가 액세스 할 수있는 사용자를 확인하기 위해 다음과 같은 하위 쿼리를 사용하고 있습니다.

SELECT user_id FROM user WHERE user_id 
     IN (SELECT user_id 
         FROM user_metadata 
         WHERE user_metadata_field_id = 1 AND field_value = 'foo')

현재 저는 변수에 하위 쿼리 문자열을 저장 한 다음 사용자 목록을 가져올 때마다 외부 쿼리에 동적으로 삽입합니다. 이렇게 한 후 "실제 문자열을 저장하는 것이 더 나을 것입니다"라고 생각했습니다 user_id.

그래서 이것을 변수에 저장하는 대신 ...

$subSql = "SELECT user_id FROM user_metadata WHERE user_metadata_field_id = 1 AND field_value = 'foo'";

... 실제로 쿼리를 수행하고 결과를 다음과 같이 저장합니다 ...

$subSql = "12, 56, 89, 100, 1234, 890";

그런 다음 로그인 한 사용자가 액세스 할 수있는 사용자를 가져와야 할 때 다음과 같이 할 수 있습니다.

$sql = "SELECT user_id FROM user WHERE user_id IN ($subSql)";

마지막으로 질문 :

MySQL INCLAUSE 에서 몇 개의 항목을 사용할 수 있습니까? 하위 SQL 문 대신 실제 ID를 저장하는 것이 매번 해당 외부 쿼리를 수행하기 위해 더 빨라야합니다.


특정 숫자부터 시작하면 IN테이블이 더 빠릅니다.

MySQL 중첩 루프에서 동일한 작업을 수행하는 것보다 많은 수의 상수 값에 대한 범위를 더 느리게 만드는 코드 내부에 무언가가 있습니다.

성능에 대한 자세한 내용은 내 블로그의이 기사를 참조하십시오.


로부터 수동 :

IN목록 의 값 수는 값에 의해서만 제한됩니다 max_allowed_packet.


Quassnoi의 응답에서 알 수 있듯이 주어진 MySql 버전의 구현 (*)에 의해 부과 된 가능한 제한도달 하기 전에 다른 실용적인 고려 사항을 우연히 발견합니다 . 따라서 관리자 (또는 IN 구성이 필요할 수있는 기타 기준) 수가 증가함에 따라 임시 (또는 영구적) 테이블 사용과 같은 문자 "IN"에 대한 대안을 사용해야합니다.

"관리자"기준에 대한 특수 처리를 고려하고 있으므로 성능상의 이유로 의견과 제안을 제공하고 싶습니다.

설명 : 이것이 조기 최적화의 경우 일 수 있습니까?
이 데이터베이스의 세부 사항, 볼륨, 복잡성 등을 알지 못합니다. 그리고 예, EAV (Entity-Attribute-Value) 형식에 대한 성능 공물을 알고 있지만 성공적인 비즈니스의 경우에도 계정 데이터베이스의 사용자 수가 10,000 명을 초과하는 경우는 거의 없습니다. 따라서 사용자 당 속성이 매우 많은 경우에도 상대적으로 작은 EAV 테이블을보고 있으므로 이러한 유형의 최적화가 필요하지 않을 수 있습니다. (반면에 다른 영역에서는 몇 가지 다른 최적화 트릭을 환영 할 수 있습니다).
또한 일반적인 사용 사례는 다른 쿼리와 비교하여 계정 데이터베이스에 대한 상대적인 몇 가지 쿼리를 포함하므로 이는 애플리케이션의 계정 관련 기능에 대한 사소한 성능 고려 사항을 무시하는 또 다른 이유입니다.

제안 : "재 정규화 된 속성"을 사용할
수 있습니다. 단일 값인 속성의 경우 특히 짧으면 엔티티 테이블 (이 경우 'USER'테이블)에서 이동 (또는 복제) 할 수 있습니다. 이것은 항목이 삽입되거나 업데이트 될 때 약간의 논리를 도입하지만 많은 조인 (또는 하위 쿼리)과 동일하며 가장 일반적인 사용 사례를 지원하기 위해 다중 필드 인덱스를 고려할 기회를 제공합니다.

(*) 한계가 있습니까?
나는 그러한 한계에 대해 읽지 않았습니다. 나는 오라클이 언젠가는 1,000 개의 제한이 있다는 것을 알고 있지만 MSSQL은 그렇지 않습니다. 물론 모든 서버에는 SQL 문의 전체 길이에 따라 제한이 있지만 이것은 정말 큰 숫자입니다! 그 사람을 우연히 발견하면 다른 문제가 있습니다 ... ;-)


MySQL의 IN 절 자체에는 이러한 제한이 없습니다. 나는 8000 개의 요소로 시도해 보았습니다. 스택 오버플로 오류는 선언 된 변수 일 수 있습니다.

참고 URL : https://stackoverflow.com/questions/1532366/mysql-number-of-items-within-in-clause

반응형