웹사이트 프로그램을 만들고 있는데 일반적인 요구사항은 다음과 같습니다.
사용자는 1~5까지 5단계로 구분됩니다. 숫자가 클수록 권한이 높아집니다.
콘텐츠가 많아요. 레벨이 높을수록 사용자에게 더 많은 콘텐츠가 표시됩니다.
예를 들어 콘텐츠는 A, B, C, D, E입니다.
사용자 그룹 1에 표시: A
사용자 그룹 2에 표시: A, B
…………
사용자 그룹 5에 표시: A, B, C , D, E
이 기능을 구현하려면 데이터베이스 인덱스를 어떻게 구축해야 할까요?
친구가 콘텐츠(주제) 테이블에 "그룹" 열을 추가하고
표시되는 사용자 레벨 1~5를 작성한 다음 group_tid
的联合索引。
然后查询tid
<100周围文章(例如当前用户组为3)时的语句就是:
SELECT * FROM topic
WHERE group
>=3 AND tid
<100 LIMIT 10;
可实际发现这种索引是先将group
>3的所有数据读出来,再进行选择查询。
假如有100万条数据,有50万个group
공동 인덱스를 생성하라고 했습니다.
tid
<100 주변의 기사를 쿼리합니다(예: 현재 사용자 그룹은 3입니다). SELECT * FROM topic
WHERE group
>=3 AND tid
<100 LIMIT 10;
실제로 이런 종류의 인덱스는
>3의 데이터를 모두 읽어온 후 선택 쿼리를 수행하는 것을 확인할 수 있습니다.
>3. 이 명령문을 실행할 때 50만 개의 유형을 필터링해야 하므로 매우 비효율적입니다.
단일 열 인덱스는 < 또는 >가 아닌 group_tid
=*와 같은 제한에만 적용되는 것 같습니다.
그래서 여기 전문가들에게 물어보고 싶습니다. 혹시 비슷한 요구사항이 있으셨나요? 인덱스나 테이블을 올바르게 생성하는 방법은 무엇입니까? 정말 감사합니다!
보충 1:
이것은 논리적인 질문입니다. 현재 group
进行了范围限制,后面的tid
还是在group
的基础上按顺序排列的。
如果我想知道group
>1且tid
<6的这种情况,不得不先把group
색인은 확립된 후 아래 그림과 유사합니다.
범위를 제한하더라도 다음 tid
는 group
=1,tid
=Agroup
=2,tid
=Agroup
=3,tid
=A
这样在内容读取时直接请求WHERE group
를 기준으로 순서대로 정렬됩니다.
tid
<6인 상황을 알고 싶다면 먼저 🎜2/3을 모두 읽어본 후 필터링해야 합니다. 🎜테이블 구조를 다시 계획하는 것이 유일한 해결책인 것 같습니다. 비슷한 경험이 있으신가요? 🎜
🎜보충 2: 🎜열성적인 친구로부터 이전에 이런 상황을 겪은 적이 있다는 유용한 답변을 방금 받았습니다. 🎜해결책은 게시 메커니즘을 수정하고 각 수준에 적합한 게시물을 게시하는 것입니다. 🎜예를 들어 콘텐츠 A의 수준이 3인 경우 게시 시 동시에 3개의 데이터 행을 생성해야 합니다. 🎜🎜=1,tid
=A🎜🎜=2, tid
=A 🎜🎜=3,tid
=A🎜 이런 식으로 콘텐츠를 읽을 때 WHERE 🎜=*를 직접 요청하면 적합한 콘텐츠를 읽을 수 있습니다. 🎜그런데 이 방법을 사용하면 관련 데이터가 많이 추가되고 중복이 발생할 수도 있습니다. 다른 해결 방법은 없을까요? 🎜
사실 당신의 생각은 이미 옳았습니다.
tid에 인덱스를 생성하고 그룹별로 테이블을 나눕니다.
그룹 >= 3개 그룹인 경우 다음과 같이 프로그램에서 sql을 동적으로 결합합니다.
으아악위의 색인이 유효하며 논리가 사용 가능합니다.
먼저 Innodb에서 인덱스 적용 여부는 < 또는 > 사용과 관련이 없다는 점을 설명하겠습니다. =를 사용한다고 해서 반드시 인덱스를 사용할 수 있다는 의미는 아닙니다. 전체 테이블 쿼리의 성능이 인덱스 검색 쿼리의 성능보다 높을 경우 MySQL은 지능적으로 인덱스를 포기하고 전체 테이블 쿼리를 선택합니다.
사진에 표시된 대로:
질문으로 돌아가서, tid<100과 같이 인덱스로 검색된 범위가 상대적으로 작은 경우 인덱스를 사용할 수 있습니다.
이 두 인덱스의 결과 집합이 크다면 생성 시간을 기준으로 지난 달의 콘텐츠만 검색하는 등 다른 필터링 조건을 추가하는 것을 고려해야 할까요?
페이지 매김 문제는 기본 키 ID로 다시 필터링할 수도 있습니다.
먼저 다음 사항을 이해해야 합니다.
테이블에 대한 쿼리의 경우 매번 최대 하나의 인덱스만 사용됩니다
결합 지수의 경우 데이터가 왼쪽에서 오른쪽으로 필터링되므로 첫 번째 필터 조건이 다음보다 크거나 작은 대상인 경우 두 번째 필터 조건은 전체 선택 영역에서 정확한 지수 범위를 갖지 않습니다. 첫 번째 필터로 필터링된 데이터
B-Tree 인덱스의 구조는 아래 그림과 같이 트리 구조와 유사합니다. 조인트 인덱스는 이 구조에서 위에서 아래로 검색되는 과정입니다.
그럼 다시 질문으로 돌아가서, 효율성을 크게 향상시키려면 공동 색인의 첫 번째 단계에서 후속 심사에 사용할 수 있는 데이터의 양을 크게 줄여야 하므로 확인하고 싶다면.
tid < 100
的话,先用tid
筛选才能够大幅度减少后续的B-Tree索引分支,所以如果要用联合索引,则应该是(tid, group)
그룹 조건의 필터링 성능이 매우 좋지 않아 인덱스만 만드는 것은 의미가 없습니다.
설명한 시나리오에 따르면 tid 값이 너무 크지 않은 한(천 단위) tid에 대한 인덱스를 생성하는 것으로 충분합니다.
tid 조건으로 필터링된 많은 양의 데이터가 여전히 걱정된다면 tid와 그룹의 통합 인덱스를 생성할 수 있습니다.
우선 제 질문에 관심을 가져주시고 답변해주셔서 정말 감사드립니다! !
문제를 해결한 후 boxsnake님의 제안에 대해 몇 가지 생각이 나서 여기에 게시하겠습니다.
group_tid
이 인덱싱 방법은 읽기 문제뿐만 아니라 페이징 문제도 해결할 수 있습니다.group_tid
这种索引方式除了解决读取之外还能解决分页问题,例如我每页文章数量是10,用户级别为3,那么读取时分别从group1、group2、group3中,
按范围
tid
예를 들어 페이지당 기사 수가 10개이고 사용자 수준이 3인 경우 읽기는 그룹1, 그룹2, 그룹3에서tid
<100 범위에 따라 각각 10개의 기사를 가져옵니다. 특정 그룹에서 조건을 충족하는 결과가 없더라도 여러 항목을 합치면 모두 다룰 수 있습니다.tid_group
这种索引方式来读取,如果需要group<=3的情况,我不知道该取多少篇文章。比方说取10篇,tid90-tid99,如果他们的group都是4,那么就无法取出符合条件的数值。
而
tid_group
在限定group
之前又必须对tid
그런데tid_group
인덱스 메소드를 사용하여 읽으면 group예를 들어 tid90-tid99라는 10개의 기사를 가져오고 해당 그룹이 모두 4개이면 조건에 맞는 값을 얻을 수 없습니다. 🎜그리고tid_group
은group
을 제한하기 전에tid
를 제한해야 사용할 수 있습니다. 🎜