首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >慢内连接6张表

慢内连接6张表
EN

Stack Overflow用户
提问于 2013-12-03 20:39:21
回答 1查看 719关注 0票数 0

对不起,我的SQL知识是业余的。

SQL:http://sqlfiddle.com/#!2/5640d/1请单击上面的链接以引用数据库结构和查询。

我有6个表,每个数据在每个表中只占一行,在所有6个表中有3个相同的列( CustgroupRandomNumberuser_id )。

Custgroup是一个组名,在组内每个数据都有一个唯一的RandomNumber

这个查询在第一次运行时非常慢(随机花了几秒钟到几分钟),之后会很快,但是对于前几页only.If,我点击第20页或30+,它将是不间断的加载(刚刚花了大约5分钟).And数据不是很多,只有5000行,这在future.And中会有很大的麻烦,我还没有添加任何WHERE子句,因为我需要对我的网站中的每一列进行过滤。(这不是我的想法,是老板的要求)。

我试图将其更改为左联接、连接和其他可以找到的方式,但加载仍然很慢。

我为所有表的user_id、Custgroup和RandomNumber添加了索引。无论如何,要解决这个问题?我从来不擅长使用JOIN,对我的数据库来说真的很慢。

或者请告诉我,如果我的桌子结构真的很糟糕,我愿意重新做它。

谢谢。

**编辑

运行解释:

代码语言:javascript
运行
复制
    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       

编辑:解释扩展..。

代码语言:javascript
运行
复制
    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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-03 22:20:45

这种结构的逻辑索引必须是

代码语言:javascript
运行
复制
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

但到了现在,我不得不问,为什么?很明显,你总是有相同用户的记录。例如:

代码语言:javascript
运行
复制
t1.Cell,t1.Name,t1.Gender,t1.Birthday
tA.Email,tA.State,tA.Address,tA.City,tA.Postcode

...it很明显,你不能有两个不同的用户在这里(在同一块的电子邮件与邮政编码告诉我,这并不是真正的一对多的关系)。

代码语言:javascript
运行
复制
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条件,并适当地修改索引和联接:

代码语言:javascript
运行
复制
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 (也可以保存重复的列)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20361207

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档