2013-11-13 1 views
0

У меня есть таблицы SQL здесьMySQL Оптимизация LEFT JOIN для большого запроса данных с той же таблицы

| 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-запрос. Благодаря!

+0

использовать группу по с оператором if он выполнил бы запрос только один раз. –

+0

Прежде всего, ваша структура таблицы сама по себе выглядит так, будто она может замедлить вас. Помимо этого у вас есть индексы во всех полезных местах (например, в столбце, на который вы присоединяетесь?) – ModulusJoe

ответ

1

Я думаю, что это решит вашу проблему или, по крайней мере, он будет работать быстрее, так как он будет получать таблицу только один раз:

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 

Посмотри здесь скрипку: http://sqlfiddle.com/#!2/f4045/11

+1

Вот что я сделал бы. – Strawberry

+1

НАЛИЧНО! 0,32 секунды! –

0

Я бы обеспечить вам индекс (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' 

Это будет идти только через основную таблицу один раз на основе только первый name, но вытащите столбцы из вторых экземпляров, не требуя MAX() или GROUP BY агрегатов.

Смежные вопросы