MySQL优化同表大数据查询的左连接

MySQL优化同表大数据查询的左连接,mysql,Mysql,我这里有一个SQL表 | id | dataid | datarow | datacolumn | datavalue _________________________________________________ | 1 | 1 | 1 | FirstName | John | 1 | 1 | 1 | LastName | Lobo | 1 | 1 | 1 | Age |

我这里有一个SQL表

| id | dataid |  datarow | datacolumn | datavalue
_________________________________________________
|  1  |  1     |     1    | FirstName   |  John
|  1  |  1     |     1    | LastName    |  Lobo
|  1  |  1     |     1    | Age         |  35
|  1  |  1     |     2    | FirstName   |  Mich
|  1  |  1     |     2    | LastName    |  Handness
|  1  |  1     |     2    | Age         |  22
|  1  |  1     |     3    | FirstName   |  Mike
|  1  |  1     |     3    | LastName    |  Longbow
|  1  |  1     |     3    | Age         |  55
它将输出类似这样的内容

FirstName  LastName Age
   John      Lobo   35
   Mich      Handness 22
   Mike      Longbow  55
SELECT DISTINCT     
        t1.datavalue AS Firstname, 
        t2.datavalue AS Lastname,
        t3.datavalue AS Age

FROM largedatatable t1 
        LEFT JOIN (SELECT datavalue,datarow FROM largedatatable WHERE           datacolumn='LastName') t2 ON t1.datarow = t2.datarow
        LEFT JOIN (SELECT datavalue,datarow FROM largedatatable WHERE datacolumn='Age') t3 ON t1.datarow = t3.datarow

WHERE t1.dataid = 1 
这给了我这样的结果

Firstname  LastName   Age
John        Lobo      35
Mich      Handness    22
Mike      Longbow     55

现在剧本做得很好;但是,如果查询是一个大数据集,那么查询速度会很慢。无论如何,我仍然可以优化这个SQL查询。谢谢

我会确保您在(datarow,datacolumn)上有一个索引来帮助您加入,但是您的加入可以简化为

SELECT 
        t1.datavalue AS Firstname, 
        t2.datavalue AS Lastname,
        t3.datavalue AS Age
   FROM 
      largedatatable t1
         LEFT JOIN largedatatable t2
            on t1.datarow = t2.datarow
           and t2.datacolumn = 'LastName'
         LEFT JOIN largedatatable t3
            on t1.datarow = t3.datarow
           and t3.datacolumn = 'Age'
   WHERE
      t1.datacolumn = 'FirstName'

这只会基于第一个名称列遍历主表一次,但会从第二个实例中提取列,而不需要MAX()或GROUP BY集合。

我认为这会解决您的问题,或者至少会运行得更快,因为它只会获取表一次:

select 
    max(case datacolumn when 'FirstName' then datavalue else '' end) as FirstName,
    max(case datacolumn when 'LastName' then datavalue else '' end) as LastName,
    max(case datacolumn when 'Age' then datavalue else '' end) as Age
from 
    large
group by datarow

查看这里的fiddle:

使用带有if语句的groupby它只需执行一次查询。首先,您的表结构本身看起来可能会减慢您的速度。除此之外,在所有有用的地方都有索引(例如,在您要加入的列上?)钉住它!0.32秒!