抱歉,我的SQL知识很业余。
SQL小提琴:http://sqlfiddle.com/#!2/5640d/1 请单击上面的链接以参考数据库结构和查询。
我有6个表,每个数据在每个表中只占一行,并且在所有6个表中我有3个相同的列Custgroup
,RandomNumber
和user_id
。
Custgroup
是一个群组名称,在群组中,每个数据都有唯一的RandomNumber
。
首次运行时查询非常慢(随机需要几秒到几分钟),之后会很快,但仅限前几页。如果我点击第20页或第30页,它将是非停止加载(刚刚花了大约5分钟)。而且数据不多,只有5000行,将来会遇到很大麻烦。我还没有添加任何WHERE子句,因为我需要对每列进行过滤在我的网站上。(不是我的想法,我的老板要求)。
我尝试将其更改为LEFT JOIN,JOIN以及我可以找到的任何其他方式,但加载速度仍然很慢。
我为所有表的user_id,Custgroup和RandomNumber添加了INDEX。 无论如何要解决这个问题?我从不擅长使用JOIN,对我的数据库来说真的很慢。
或者,如果我的桌子结构非常糟糕,请告诉我,我愿意重做它。
感谢。
**被修改
RUN EXPLAIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE tE ALL NULL NULL NULL NULL 5685
1 SIMPLE tA ALL NULL NULL NULL NULL 6072 Using join buffer
1 SIMPLE t1 ref user_id,Custgroup,RandomNumber RandomNumber 23 func 1 Using where
1 SIMPLE tB ALL NULL NULL NULL NULL 5868 Using where; Using join buffer
1 SIMPLE tC ALL NULL NULL NULL NULL 6043 Using where; Using join buffer
1 SIMPLE tD ALL NULL NULL NULL NULL 5906 Using where; Using join buffer
Keyname Type Unique Packed Column Cardinality Collation Null Comment
PRIMARY BTREE Yes No ID 6033 A
RandomNumber BTREE No No RandomNumber 6033 A
Custgroup BTREE No No Custgroup 1 A
user_id BTREE No No user_id 1 A
编辑:EXPLAIN EXTENDED .....
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE tE ALL NULL NULL NULL NULL 6084 100.00
1 SIMPLE t1 ref user_id,Custgroup,RandomNumber RandomNumber 23 func 1 100.00 Using where
1 SIMPLE tB ALL NULL NULL NULL NULL 5664 100.00 Using where; Using join buffer
1 SIMPLE tC ALL NULL NULL NULL NULL 5976 100.00 Using where; Using join buffer
1 SIMPLE tA ALL NULL NULL NULL NULL 6065 100.00 Using where; Using join buffer
1 SIMPLE tD ALL NULL NULL NULL NULL 6286 100.00 Using where; Using join buffer
答案 0 :(得分:3)
这种结构的逻辑索引必须是
CREATE INDEX UserAddedRecord1_ndx ON UserAddedRecord1 (user_id, Custgroup, RandomNumber);
CREATE INDEX UserAddedRecord1_A_ndx ON UserAddedRecord1_A (Custgroup, RandomNumber);
CREATE INDEX UserAddedRecord1_B_ndx ON UserAddedRecord1_B (Custgroup, RandomNumber);
CREATE INDEX UserAddedRecord1_C_ndx ON UserAddedRecord1_C (Custgroup, RandomNumber);
CREATE INDEX UserAddedRecord1_D_ndx ON UserAddedRecord1_D (Custgroup, RandomNumber);
CREATE INDEX UserAddedRecord1_E_ndx ON UserAddedRecord1_E (Custgroup, RandomNumber);
如果您要添加WHERE
子句,他们应该在 JOIN
条件之前进入相关索引(前提是您运行等于或{{1搜索,例如City =" New York")。例如,如果City位于UserAddedRecord1_B中,则UserAddedRecord1_B_ndx应为IN
。
但是在这一点上,我不得不问,为什么?显然,您始终为同一用户提供记录。例如:
City, Custgroup, RandomNumber
...很明显,你不能在这里拥有两个不同的用户(并且邮政编码与邮政编码在同一个区块中告诉我这不是真正意图作为一对多的关系)。
t1.Cell,t1.Name,t1.Gender,t1.Birthday
tA.Email,tA.State,tA.Address,tA.City,tA.Postcode
这些是单个大型用户信息表单的所有部分",分为(可选?)部分。
我猜测这种结构源于某种遗留/框架系统,它将表单提交部分映射到表。这样某人可能在表B,C和E中有一个条目,在表A,C和D中有其他人。
如果这是真的,并且如果tB.Website,tB.Description,
tC.Model,tC.Capital,tC.Registry,tC.NoEmployees,
tD.SetUpDate,tD.PeopleInCharge,tD.Certification,tD.AddOEM,
tD.NoResearcher,tD.RoomSize,tD.RegisterMessage,
tE.WebsiteName,tE.OriginalWebsite,tE.QQ,tE.MSN,tE.Skype
对于所有表都相同,那么将此更快的一种方法是在user_id
上明确添加条件每个表,并适当修改索引和JOIN:
user_id
要做的是将所有表合并到一个表中,并将所有字段放在一行中,然后,为了传统目的,您可以创建CREATE INDEX UserAddedRecord1_ndx ON UserAddedRecord1 (user_id, Custgroup, RandomNumber);
CREATE INDEX UserAddedRecord1_A_ndx ON UserAddedRecord1_A (user_id, Custgroup, RandomNumber);
CREATE INDEX UserAddedRecord1_B_ndx ON UserAddedRecord1_B (user_id, Custgroup, RandomNumber);
CREATE INDEX UserAddedRecord1_C_ndx ON UserAddedRecord1_C (user_id, Custgroup, RandomNumber);
CREATE INDEX UserAddedRecord1_D_ndx ON UserAddedRecord1_D (user_id, Custgroup, RandomNumber);
CREATE INDEX UserAddedRecord1_E_ndx ON UserAddedRecord1_E (user_id, Custgroup, RandomNumber);
... FROM UserAddedRecord1 t1
JOIN UserAddedRecord1_A tA USING (user_id, CustGroup, RandomNumber)
JOIN UserAddedRecord1_B tB USING (user_id, CustGroup, RandomNumber)
JOIN UserAddedRecord1_C tC USING (user_id, CustGroup, RandomNumber)
JOIN UserAddedRecord1_D tD USING (user_id, CustGroup, RandomNumber)
JOIN UserAddedRecord1_E tE USING (user_id, CustGroup, RandomNumber)
WHERE t1.user_id = '1'
看起来比如表1,A,B,C,D和E,每个都有一个"垂直"元组的分区。但是你会在包含所有字段的完整表格上运行的大VIEWs
(并且你也可以保存在重复的列上)。