2013-04-30 2 views
0

У меня есть проблема с этим MySQL Query:Слишком длинный запрос с более чем 1 подзапроса

SELECT 
    CONCAT('Kantor ', o.nama) AS nama, 
    IF(sj.jenis = 1, CONCAT(sj.sebutan, ' ' , sj.nama), sj.nama) AS sebutan, 
    (
     SELECT 
      COUNT(fj.id) 
     FROM 
      tbl_formasijabatan fj 
     WHERE 
      fj.sebutanId = sj.id AND 
      fj.status = 1  AND 
      fj.orgId  = o.id 
    ) AS total 

FROM 
    tbl_organisasi o 
    RIGHT JOIN tbl_formasijabatan fjj ON fjj.orgId = o.id 
    RIGHT JOIN tbl_sebutanjabatan sj ON sj.id  = fjj.sebutanId 
WHERE 
    o.id = 1 AND 
    o.unitKerja > 0 
GROUP BY 
    o.nama, 
    sj.nama 

Этот запрос очень длинный, занимает 66 секунд, только чтобы получить 330 строк.

Как ускорить извлечение данных, по крайней мере, в течение 1-10 секунд?

Ну ваш комментарий очень полезен для меня.

Если для этого требуются данные, я отправлю базу данных.

спасибо

+0

Места индекса для столбцов первичного ключа для используемых tables.Indexes помогают в работе и быстром поиске. – MahaSwetha

+0

@ Dai thx для отредактированного моего вопроса ... – Fikrizal

ответ

0

В большинстве случаев вам просто не хватает указателя на столбцы в предложении where и в предложении join.

Вы должны поместить указатель на

  • tbl_formasijabatan.orgId
  • tbl_formasijabatan.sebutanId
  • tbl_organisasi.unitKerja

    alter table `tbl_formasijabatan` add index(`orgId`); 
    alter table `tbl_formasijabatan` add index(`sebutanId`); 
    alter table `tbl_organisasi` add index(`unitKerja`); 
    

вы можете также назвать индекс, но это было бы самым быстрым способом. После этого ваш запрос должен быть довольно быстрым, поскольку он не так много компилируется. Фактически, группа будет потреблять больше всего времени, поскольку для нее нужна временная таблица. Если вы хотите копать глубже здесь вы могли бы посмотреть здесь

http://dev.mysql.com/doc/refman/5.0/en/group-by-optimization.html

Bottom Line: не начать с действием индекса shutgun. Вы должны указывать только те столбцы, которые используются для объединений и во множестве операторов. В противном случае вы снова ухудшите производительность. Хорошая отправная точка будет

http://www.percona.com/files/presentations/WEBINAR-tools-and-techniques-for-index-design.pdf

+0

Благодарим вас за ответ. ваши ответы разрешают мою проблему. Теперь мой запрос намного быстрее, прежде чем я не использовал индекс, но теперь его использую, оказывается, я так знаю, что такое функция индекса. – Fikrizal

1

Может быть, вы могли бы переместить этот подзапрос в соединение, которое должно дать вам улучшение производительности, попробовать что-то вроде:


SELECT CONCAT('Kantor ', o.nama) AS nama, if(sj.jenis = 1, CONCAT(sj.sebutan, ' ', sj.nama), sj.nama) AS sebutan, X.total 
FROM tbl_organisasi o 
RIGHT JOIN tbl_formasijabatan fjj ON fjj.orgId = o.id 
RIGHT JOIN tbl_sebutanjabatan sj ON sj.id = fjj.sebutanId 
JOIN (SELECT COUNT(fj.id) total, fj.id 
    FROM tbl_formasijabatan fj 
    WHERE fj.sebutanId = sj.id 
    AND fj.status = 1 
    AND fj.orgId = o.id 
    GROUP BY fj.id) X 
ON X.id = fjj.id 
WHERE o.id = 1 AND o.unitKerja > 0 
GROUP BY o.nama , sj.nama 

Извините за плохое форматирование, дайте мне шанс и дайте мне знать.

+0

спасибо за совет – Fikrizal

+0

Присоединение к подзадачу, подобному этому, должно быть более качественным (хотя нужны и индексы). Однако я думаю, что @ Kartikya сделал небольшую опечатку здесь. В подзапросе я думаю, что он должен возвращать fj.ordId, а не fj.id, а также group by fj.ordId, а не fj.id. Далее следует удалить строку AND fj.orgId = o.id. – Kickstart