对不起,我的SQL知识是业余的。
SQL:http://sqlfiddle.com/#!2/5640d/1请单击上面的链接以引用数据库结构和查询。
我有6个表,每个数据在每个表中只占一行,在所有6个表中有3个相同的列( Custgroup
、RandomNumber
和user_id
)。
Custgroup
是一个组名,在组内每个数据都有一个唯一的RandomNumber
。
这个查询在第一次运行时非常慢(随机花了几秒钟到几分钟),之后会很快,但是对于前几页only.If,我点击第20页或30+,它将是不间断的加载(刚刚花了大约5分钟).And数据不是很多,只有5000行,这在future.And中会有很大的麻烦,我还没有添加任何WHERE子句,因为我需要对我的网站中的每一列进行过滤。(这不是我的想法,是老板的要求)。
我试图将其更改为左联接、连接和其他可以找到的方式,但加载仍然很慢。
我为所有表的user_id、Custgroup和RandomNumber添加了索引。无论如何,要解决这个问题?我从来不擅长使用JOIN,对我的数据库来说真的很慢。
或者请告诉我,如果我的桌子结构真的很糟糕,我愿意重新做它。
谢谢。
**编辑
运行解释:
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
编辑:解释扩展..。
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
发布于 2013-12-03 22:20:45
这种结构的逻辑索引必须是
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
条件之前进入相关索引(前提是运行相等或IN
搜索,例如City= "New“)。例如,如果城市在UserAddedRecord1_B,那么UserAddedRecord1_B_ndx应该是City, Custgroup, RandomNumber
。
但到了现在,我不得不问,为什么?很明显,你总是有相同用户的记录。例如:
t1.Cell,t1.Name,t1.Gender,t1.Birthday
tA.Email,tA.State,tA.Address,tA.City,tA.Postcode
...it很明显,你不能有两个不同的用户在这里(在同一块的电子邮件与邮政编码告诉我,这并不是真正的一对多的关系)。
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
这些都是单个大型“用户信息表单”的所有部分,分为(可选的?)部分。
我推测,这种结构是由某种遗留/框架系统产生的,该系统将表单提交部分映射到表中。因此,某人可能在表B、C和E中有一个条目,而在表A、C和D中可能有其他人。
(如果这是真),如果所有表的user_id
都是相同的,那么让它更快的一种方法是为每个表显式地添加一个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
,每个表都有一个元组的“垂直”分区。但是,在包含所有字段的完整表上运行的大型SELECT
(也可以保存重复的列)。
https://stackoverflow.com/questions/20361207
复制相似问题