2015-09-21 3 views
1

У меня есть запрос, в котором данные поступают из нескольких таблиц.оптимизировать запрос с несколькими таблицами

SELECT iUserID, 
     iUserID AS userID, 
     (CASE vUSBG 
      WHEN 1 THEN 'Yes' 
      WHEN 0 THEN 'No' 
     END) AS vUSBG, 
     concat(vFirstname,' ',vLastname) AS Name, 
     vEmail, 
     eType, 
     eStatus, 
     tAddedDate, 
     eExpert, 
     eAdmin, 

    (SELECT count(iUserID) AS total 
    FROM tbl_friend 
    WHERE iUserID = tbl_user.iUserID) AS count_f, 

    (SELECT COUNT(*) 
    FROM bar_followers 
    WHERE bar_followers.iUserID = tbl_user.iUserID) AS bar_follows, 

    (SELECT COUNT(b.iBrandID) 
    FROM tbl_company_follow, 
     tbl_brand b 
    WHERE tbl_company_follow.iUserID = tbl_user.iUserID 
    AND b.iCompanyID = tbl_company_follow.iCompanyID) AS brand_follows, 

    (SELECT sum(points) AS totalpoints 
    FROM tbl_points, 
     tbl_post p 
    WHERE iUserID = tbl_user.iUserID 
    AND p.iPostID = tbl_points.post_id) AS countPoints 
FROM tbl_user 

Этот запрос принял 8.3595 seconds

Как я минимизировать время?

+1

http://sqlformat.org/ - ваш друг :) – lad2025

+0

, но как я могу управлять им в этом большом запросе? –

+0

но он принимает '8.3595 сек' –

ответ

3

Ваш запрос является разумным, за исключением отсутствия явного синтаксиса join.

Проверьте, чтобы убедиться, что у вас есть следующие индексы:

  • tbl_friend(iUserId)
  • bar_followers(iUserID)
  • tbl_company_follow(iUserID, iCompanyID)
  • tbl_brand(iCompanyID)
  • tbl_post(iUserID, iPostID)
  • tbl_points(post_id, points)

Однако, в зависимости от размера ваших данных, 8-9 секунд может быть разумным.

+0

есть только 750 записей, и это занимает много времени –

+0

спасибо .. сейчас Запрос взял' 0.0229 сек' –

+0

@bluto. , , 99,7%. Неплохо;) –

1

Трудно судить о том, разумно ли использовать время в 10-й секунде, не зная размеров ваших таблиц. Это может быть близко к лучшему, что вы можете сделать.

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

SELECT tu.field, tu.field, ... 
     a.count_f, 
     b.bar_follows, 
     ... 
    FROM tbl_user tu 
    LEFT JOIN (
       SELECT count(*) AS count_f, iUserID 
       FROM tbl_friend 
       GROUP BY iUserID 
     ) a ON tu.iUserID = a.iUserId 
    LEFT JOIN (
       SELECT count(*) AS bar_follows, iUserID 
       FROM bar_followers 
       GROUP BY iUserId 
     ) b ON tu.iUserID = b.iUserId 
... 

Здесь происходят две связанные вещи. Сначала каждый COUNT() вещь COUNT(*). Это позволяет выполнить запрос, не глядя на содержимое каждой строки.

Во-вторых, зависимые подзапросы в списке столбцов заменяются подзапросами, которые обрабатывают необходимые вам данные. Это может помочь, поскольку планировщик запросов может выполнять каждый подзапрос только один раз.

Gordon's right об индексах.

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