복붙노트

[SQL] "절에"내 항목의 MySQL의 수

SQL

"절에"내 항목의 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_ids의 문자열을 저장하기에 더 좋을 가지고있다."

그래서 그 대신 변수에이를 저장 ...

$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의 IN 절에서 얼마나 많은 항목을 사용할 수 있습니까? 서브 SQL 문을 대신 실제 ID를 저장 빠르게 오른쪽이 외부 쿼리를 매번 수행 할 가지고있다?

해결법

  1. ==============================

    1.특정 번호에서 시작하여, IN 테이블이 빠릅니다.

    특정 번호에서 시작하여, IN 테이블이 빠릅니다.

    MySQL은 속도가 느린 중첩 루프에서 같은 일을보다 상수 값의 큰 숫자를 통해 범위를 구축하게 해당 코드 안에 뭔가가있다.

    성능 자세한 내용은 내 블로그에서이 문서를 참조하십시오 :

  2. ==============================

    2.수동에서 :

    수동에서 :

    IN을 목록에있는 값의 개수 만의 max_allowed_packet 값에 의해 제한된다.

  3. ==============================

    3.Quassnoi의 반응에 암시 된 바와 같이, 주어진 MySQL 버전의 구현 (*)에 의해 부과 가능한 제한을 타격하기 전에 다른 실제적인 고려에 따라 하나의 실수를 한단다. (AN IN 구조를 필요로하거나 다른 기준) 관리자 사용자의 수가 증가함에 따라서, 하나는 임시 (또는 영구) 테이블의 사용으로 문자 그대로의 "IN", 대안을 사용하도록 노력해야한다.

    Quassnoi의 반응에 암시 된 바와 같이, 주어진 MySQL 버전의 구현 (*)에 의해 부과 가능한 제한을 타격하기 전에 다른 실제적인 고려에 따라 하나의 실수를 한단다. (AN IN 구조를 필요로하거나 다른 기준) 관리자 사용자의 수가 증가함에 따라서, 하나는 임시 (또는 영구) 테이블의 사용으로 문자 그대로의 "IN", 대안을 사용하도록 노력해야한다.

    당신은 "관리자 사용자"기준의 특수 처리를 고려하고 있기 때문에, 성능을 위해, 나는 의견과 제안을 제공하고 싶습니다.

    코멘트 :이 조기 최적화의 경우가 될 수 있을까? 나는, 그래, 내가 EAV (엔티티 - 속성 - 값) 형식으로 지불하는 일부 성능 공물을 알고이 데이터베이스, 그것의 양, 복잡성 등과의 세부 사항 모르고 있어요,하지만 난 생각 해요 심지어 성공적인 비즈니스를 들어, 10,000 명의 사용자를 초과하는 데이터베이스 거의 수를 차지한다. 그래서 심지어 사용자 당 아주 많은 속성을 가진 우리는 여전히 최적화의이 유형을 필요로하지 않을 수 있습니다 상대적으로 작은 EAV 테이블에서 찾고 있습니다. (반면에 몇 가지 다른 최적화 기법은 다른 분야에서 환영받을 수 있습니다). 또한, 일반적인 사용 사례는 다른 쿼리를 기준으로 계정 데이터베이스에 상대적으로 몇 가지 질문을 포함하고,이 때문에 응용 프로그램의 계정 관련 기능에 대한 비 사소한 성능 고려 deffer하는 또 다른 이유입니다.

    제안 : 어쩌면 "재 정규화 속성"을 사용 (이 경우 '사용자'테이블) 엔티티 테이블에 찍어 값, 그리고 그들이 짧은 경우 특히, 이동 (또는 복제) 할 수있는 속성하십시오. 이 시간 항목에서 논리의 비트를 삽입하거나 업데이트 소개하고 있지만, SAMES 많은 조인 (또는 하위 쿼리) 또한 가장 일반적인 사용 사례를 지원하기 위해 다중 필드 인덱스를 고려하는 기회를 제공합니다.

    (*)는 LIMT이 있습니까? 나는 어떤 그러한 제한에 대한 읽지 않은; 나는 오라클이 알고 시간에 1,000 한계를 (했다), MSSQL하지 않습니다; 물론 모든 서버는 SQL 문의 전체 길이에 따라 제한이 없지만, 이것은 정말 큰 숫자입니다! 만약 하나 하나에 따라 지금까지 우연히 발견, 그 / 그녀가 다른 문제가 ... ;-)

  4. ==============================

    4.MySQL의의 IN 절 자체는 제한이 없습니다. 나는 나를 위해 8000 요소의 작업 벌금했습니다. 변수가 선언의 스택 오버플로 오류가있을 수

    MySQL의의 IN 절 자체는 제한이 없습니다. 나는 나를 위해 8000 요소의 작업 벌금했습니다. 변수가 선언의 스택 오버플로 오류가있을 수

  5. ==============================

    5.당신이 IN () 절 내에 1000 개 이상의 값이있는 경우 MariaDB 자동으로 성능 개선을 위해 임시 테이블을 만들 것으로 보인다. 당신은 Explain을 사용하여이 문제를 볼 수 있습니다.

    당신이 IN () 절 내에 1000 개 이상의 값이있는 경우 MariaDB 자동으로 성능 개선을 위해 임시 테이블을 만들 것으로 보인다. 당신은 Explain을 사용하여이 문제를 볼 수 있습니다.

  6. from https://stackoverflow.com/questions/1532366/mysql-number-of-items-within-in-clause by cc-by-sa and MIT license