通过连接有序数据进行查询优化

时间:2012-11-30 11:08:45

标签: optimization join

我的问题涉及查询sql的优化。

我的查询会检索成员列表及其上一次培训。

为了获得最新的培训,我会在查询结果上加入一个返回所有成员的完整培训列表。

这个查询有效,但速度非常慢,如果有人能找到更快的执行解决方案,我真的很感兴趣。

我的查询(约16秒):

SELECT 
    m.nom,
    m.prenom,
    m.ville,
    m.maj,
    mbf.libelle,
    mbf.datefin,
    m.id as idmb
FROM
    membres m
    LEFT JOIN (
        select *
        from membreform
        where idformation = 1
        order by datefin DESC
    ) as mbf ON mbf.idmembre = m.id
WHERE
    role > 0 AND visible = 1
group by m.id
ORDER BY m.maj DESC
limit 0 , 20

我的数据结构:

  

membreform(1000个条目)

  • id int(11)NOT NULL AUTO_INCREMENT,
  • idmembre int(11)NOT NULL,
  • libelle varchar(128)NOT NULL,
  • idformation int(11)NOT NULL,
  • datedebut日期非空,
  • datefin date NOT NULL DEFAULT'0000-00-00',
  • descript text NOT NULL,
  • KEY idid),
  • KEY idmembreidmembre),
  • KEY idformationidformation
  

membres(500个条目)

  • id int(3)NOT NULL AUTO_INCREMENT,
  • nom varchar(255)NOT NULL,
  • prenom varchar(255)NOT NULL,
  • ville varchar(255)NOT NULL,
  • email varchar(255)NOT NULL,
  • maj datetime NOT NULL,
  • role tinyint(4)NOT NULL DEFAULT'1',
  • PRIMARY KEY(id),
  • KEY rolerole),
  • KEY majmaj

我测试了另一种方式(大约0.40s),但我发现它真的很干净

SELECT 
    m.nom,
    m.prenom,
    m.ville,
    m.maj,
    m.id as idmb,
    (select 
            libelle
        from
            membreform
        where
            idformation = 1
                AND m.id = membreform.idmembre
        order by datefin DESC
        limit 1
    ) libelle,
    (select 
            datefin
        from
            membreform
        where
            idformation = 1
                AND m.id = membreform.idmembre
        order by datefin DESC
        limit 1
    ) datefin
FROM
    membres m
WHERE
    role > 0 AND visible = 1
group by m.id
ORDER BY m.maj DESC
limit 0 , 20

我愿意接受任何建议,因为我有点卡住了

谢谢

1 个答案:

答案 0 :(得分:0)

您可以使用临时表来提高性能。例如(MS SQL) 1步 - 通过添加所有相关的where条件

,将memberform数据导入临时表

选择* INTO #TempMembreform 来自membreform 其中idformation = 1 ... 由datefin DESC命令

2步 - 按照上面第一个示例中的操作执行左外连接。 E.g。

SELECT 
    m.nom,
    m.prenom,
    m.ville,
    m.maj,
    mbf.libelle,
    mbf.datefin,
    m.id as idmb
FROM
    membres m
    LEFT JOIN #TempMembreForm as mbf 
        ON mbf.idmembre = m.id
WHERE
    role > 0 AND visible = 1
group by m.id
ORDER BY m.maj DESC
limit 0 , 20

3步 - 如果数据不是mision crical,则添加NOLOCK关键字(例如银行交易)

select *
INTO #TempMembreform 
from membreform WITH(NOLOCK)
where idformation = 1
order by datefin DESC

SELECT 
    m.nom,
    m.prenom,
    m.ville,
    m.maj,
    mbf.libelle,
    mbf.datefin,
    m.id as idmb
FROM
    membres m with(nolock)
    LEFT JOIN #TempMembreForm as mbf 
        ON mbf.idmembre = m.id
WHERE
    role > 0 AND visible = 1
group by m.id
ORDER BY m.maj DESC
limit 0 , 20

My profile