【发布时间】:2019-11-16 04:05:44
【问题描述】:
这里是架构:-
Student_Details
ID | Student_id | Name | Value
1 | 2 | City | NewYork
2 | 2 | Height | 5'11'
3 | 2 | Class | B
4 | 2 | RollNo | 265454
5 | 2 | Credit | 800
6 | 3 | City | Manila
7 | 3 | Height | 5'10'
8 | 3 | Type | International
9 | 3 | RollNo | 2653
10 | 1 | Address | Main Street
11 | 1 | Height | 5'9'
12 | 1 | TST | 21.54
13 | 1 | CCA | 242
13 | 1 | SEX | Male
Students
ID | Name | Age | AddedOn
1 | Alpha | 27 | 20 Jan 2019
2 | Beta | 15 | 19 Jan 2019
3 | Gamma | 18 | 20 Jan 2019
Student_Dep_Map
ID |DEP_ID | Student_id
1 | 4 | 2
2 | 2 | 1
Department
ID| Name
1 | Science
2 | Physics
3 | Chemistry
4 | Psychology
所以搜索围绕着Students,我们需要用'City','Height' or 'TST',Student in which Departments,Added On,Age等各种搜索条件来搜索Students,基本上所有这些表. 动态搜索。此外,输出搜索还应包含每个表中的一些固定详细信息。所以我用 pivot 进行了这个查询。
select distinct s.*
FROM students s
LEFT JOIN ( SELECT s.ID as s_id, group_concat(distinct d.name SEPARATOR ', ') as ASSIGNED_DEPT FROM students s
JOIN Student_Dep_Map sdp JOIN Department d on sdp.DEP_ID = d.ID ON sdp.Student_id=s.id GROUP BY s.id ) aa ON aa.s_id = s.ID
LEFT JOIN ( SELECT DISTINCT student_id,
MAX(if(Name = 'TST', value, null)) as TST,
MAX(if(Name = 'Height', value, null)) as HEIGHT,
MAX(if(Name = 'CITY', value, null)) as CITY,
MAX(if(Name = 'SEX', value, null)) as SEX,
MAX(if(Name = 'RollNo', value, null)) as ROLLNO
FROM student_detials tip GROUP BY student_id ) sd ON sd.student_id = s.ID
WHERE 1=1 AND SD.SEX = 'Male' LIMIT 0,100 ;
AND 条件是通过查询生成器动态添加的。
挑战是!这个查询太慢了,随着表中记录的增加,查询变得非常慢。我确实使用了解释来理解查询计划。如果我离开索引&只谈论优化查询计划。 我注意到当我使用数据透视时,即使搜索条件来自主表学生,查询计划在透视学生详细信息时仍会遍历几乎所有记录。 有什么方法可以限制加入,直到找到 100 条学生记录。 一种方法是为每个表编写子查询以限制结果,但有没有更好的方法来处理这个? 我需要限制 joins 而不仅仅是 joins 之后的结果,因此 Query 会导致更快的获取。
注意:对不起,我不能发布真实的表格,它只是模拟数据。
【问题讨论】:
-
感谢您的回复。想加几分。正如我所说的搜索是动态的,搜索条件也可以属于学生表或部门,例如有多少学生属于物理系或有多少学生年龄小于 27 岁等。
-
我无法将这些“性别”、“身高”列添加到学生详细信息中,这是小样本数据,实际问题有更多 200 个唯一名称值。定义学生的对可能是学生完全独特的,也可能是每个学生都存在的领域。我们尝试在 student 表中添加任何属性。学生详细信息中有额外的属性。谢谢
-
另外,输出结果可以有固定的结果集,比如所有的s.*和一些student_Details的pivot属性,分配dept。
-
阅读 EAV 架构。您的变体非常笨拙且效率低下。
标签: mysql sql query-optimization entity-attribute-value