ФорумРазработкаБазы данных → Профи, подсобите по пересечению

Профи, подсобите по пересечению

  • Абырвалг

    Сообщения: 6476 Репутация: N Группа: Джедаи

    Spritz 8 февраля 2011 г. 7:32

    Что имеется:
      Люди (users).
     Места (places). Например парк культуры и отдыха, театр, дворец спорта
     Мероприятия (rides). Ну это когда я решил собрать компанию и сходить на балет а потом в пивбар

    Соответственно таблицы-связки:
     rides2users - кто идет на мероприятие
     places2rides - какие места будем посещать


    Что нужно:
    1) Получить список мест, где я был хоть 1 раз

    SELECT
     DISTINCT p.id, p.*
    FROM
    places AS p
     LEFT JOIN places2rides pr ON pr.place_id=p.id
       LEFT JOIN rides2users ru ON ru.place_id=pr.place_id
    WHERE
     ru.user_id = %me%
     
    окей


    2) Добавить к прошлой выборке количество мероприятий, которые происходили в местах

    SELECT
     DISTINCT p.id, p.*,
     (SELECT COUNT(*) FROM places2rides AS pr1 WHERE pr1.place_id=p.id) AS rides_count
    FROM
    places AS p
     LEFT JOIN places2rides pr ON pr.place_id=p.id
       LEFT JOIN rides2users ru ON ru.place_id=pr.place_id
    WHERE
     ru.user_id = %me%


    окей, хотя такой подзапрос не очень хорош, лучше джоин ебануть наверно


    3) Добавить к прошлой выборке количество людей, которые там были хоть 1 раз

    SELECT
     DISTINCT p.id, p.*,
     (SELECT COUNT(*) FROM places2rides AS pr1 WHERE pr1.place_id=p.id) AS rides_count,
     (
       SELECT COUNT(DISTINCT ru1.user_id)
       FROM places2rides AS pr2
         LEFT JOIN rides2users ru1 ON ru1.place_id=p.id
       WHERE pr2.place_id=p.id) AS users_count
    FROM
    places AS p
     LEFT JOIN places2rides pr ON pr.place_id=p.id
       LEFT JOIN rides2users ru ON ru.place_id=pr.place_id
    WHERE
     ru.user_id = %me%


    психодел какой-то.

    До этого времени запросы работают относительно быстро. Если у вас есть замечания и предложения - буду рад их услышать.


    4) А теперь еще одно условие к прошлой выборке - нужно не все места, а только те, которые я вместе с Ваней посещал

    SELECT
     DISTINCT p.id, p.*,
     (SELECT COUNT(*) FROM places2rides AS pr1 WHERE pr1.place_id=p.id) AS rides_count,
     (
       SELECT COUNT(DISTINCT ru1.user_id)
       FROM places2rides AS pr2
         LEFT JOIN rides2users ru1 ON ru1.place_id=p.id
       WHERE pr2.place_id=p.id) AS users_count
    FROM
    places AS p
     LEFT JOIN places2rides pr ON pr.place_id=p.id
       LEFT JOIN rides2users ru ON ru.place_id=pr.place_id
     LEFT JOIN places2rides pr3 ON pr3.place_id=p.id
       LEFT JOIN rides2users ru3 ON ru3.place_id=pr3.place_id
    WHERE
     ru.user_id = %me% AND ru3.user_id = %ivan%


    И все. Наступает кромешний пиздец. Запрос выполняется до 30 секунд. Че делать, господа?
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 8 февраля 2011 г. 7:34, спустя 2 минуты 41 секунду

    ебать в рот
    Спустя 62 сек.
    1) Получить список мест, где я был хоть 1 раз

    отсюда в первом запросе INNER JOIN. впиши его, время запроса явно упадет в х раз сразу
    Сапожник без сапог
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 8 февраля 2011 г. 7:58, спустя 23 минуты 50 секунд

    А експлейны можно?
    adw/0
  • Абырвалг

    Сообщения: 6476 Репутация: N Группа: Джедаи

    Spritz 8 февраля 2011 г. 8:04, спустя 6 минут 6 секунд

    да, вечером сделаю. Я просто пока на работе, накидал запросы, думал может невооруженным глазом сходу найдете какой-то косяк.

    adw0rd, но вот 2 таких одинаковых джоина, что бы можно было сделать ru.user_id = %me% AND ru3.user_id = %ivan% - это нормально?
  • Абырвалг

    Сообщения: 6476 Репутация: N Группа: Джедаи

    Spritz 8 февраля 2011 г. 12:39, спустя 4 часа 34 минуты 44 секунды

    EXPLAIN
    SELECT
    DISTINCT p.Message_ID, p.Type, p.Name,
    (SELECT COUNT(*) FROM RidePlace as rp WHERE rp.Place_ID=p.Message_ID) AS RidesCount,
    (
    SELECT
    COUNT(DISTINCT User_ID)
    FROM
    RideUser AS ru
    WHERE
    ru.Ride_ID IN (
    SELECT rp1.Ride_ID
    FROM RidePlace as rp1
    WHERE rp1.Place_ID=p.Message_ID
    )
    ) AS RidersCount
    FROM
    Message49 as p

    LEFT JOIN
    RidePlace rp2 ON rp2.Place_ID=p.Message_ID
    LEFT JOIN
    RideUser ru1 ON ru1.User_ID=1 AND ru1.Ride_ID=rp2.Ride_ID

    LEFT JOIN
    RidePlace rp3 ON rp3.Place_ID=p.Message_ID
    LEFT JOIN
    RideUser ru2 ON ru2.User_ID=4561 AND ru2.Ride_ID=rp3.Ride_ID

    WHERE
    ru1.User_ID=1 AND
    ru2.User_ID=4561
    LIMIT 0,10
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 8 февраля 2011 г. 12:55, спустя 15 минут 43 секунды

    еще блядь раз скажу - INNER JOIN попробуй :-)
    Сапожник без сапог
  • Абырвалг

    Сообщения: 6476 Репутация: N Группа: Джедаи

    Spritz 8 февраля 2011 г. 12:59, спустя 4 минуты 41 секунду

    та пробовал - та же самая ебота, все те же 25-30 секунд
  • fgets

    Сообщения: 1099 Репутация: N Группа: Кто попало

    Spritz 8 февраля 2011 г. 13:03, спустя 3 минуты 24 секунды

    А тип таблиц какой?
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 8 февраля 2011 г. 13:04, спустя 1 минуту 41 секунду

    ладно ебись))) тут или дамп, или сам. дамп не даешь - ебись сам))
    Сапожник без сапог
  • Абырвалг

    Сообщения: 6476 Репутация: N Группа: Джедаи

    Spritz 8 февраля 2011 г. 13:07, спустя 2 минуты 49 секунд

    myisam
    Спустя 44 сек.
    phpdude, так ты не просил, епт. Ща дамп сделаю, отправлю в личку
  • fgets

    Сообщения: 1099 Репутация: N Группа: Кто попало

    Spritz 8 февраля 2011 г. 13:10, спустя 3 минуты 12 секунд

    мастера myisam на пiха.ру
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 8 февраля 2011 г. 13:41, спустя 30 минут 52 секунды

    если до завтра не решишь - посмотрю, у тебя слишком большой запрос для моего вечернего мозга - нихуя не соображаю чето уже, не выспался седня
    Сапожник без сапог
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 8 февраля 2011 г. 16:12, спустя 2 часа 30 минут 33 секунды

    Абырвалг,и мне дамп дай в личку
    adw/0
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 8 февраля 2011 г. 17:18, спустя 1 час 6 минут 12 секунд

    дай еще дампы для этих таблиц
    SELECT
    DISTINCT p.id, p.*,
    (SELECT COUNT(*) FROM places2rides AS pr1 WHERE pr1.place_id=p.id) AS rides_count
    FROM
    places AS p
    LEFT JOIN places2rides pr ON pr.place_id=p.id
    LEFT JOIN rides2users ru ON ru.place_id=pr.place_id
    WHERE
    ru.user_id = %me%


    и проверь чтобы все таблицы которые ты упоминаешь были в дампе
    либо, если они сменили название, то и в посте поменяй
    Спустя 118 сек.

    RideUser ru1 ON ru1.User_ID=1 AND ru1.Ride_ID=rp2.Ride_ID

    RideUser ru2 ON ru2.User_ID=4561 AND ru2.Ride_ID=rp3.Ride_ID
    ….
    WHERE ru1.User_ID=1 AND ru2.User_ID=4561


    а зачем в ON/WHERE поместил тоже самое?
    adw/0
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 8 февраля 2011 г. 17:30, спустя 11 минут 40 секунд


    EXPLAIN
    SELECT
    DISTINCT p.Message_ID, p.Type, p.Name,
    (SELECT COUNT(*) FROM RidePlace as rp WHERE rp.Place_ID=p.Message_ID) AS RidesCount,
    (
    SELECT
    COUNT(DISTINCT User_ID)
    FROM
    RideUser AS ru
    WHERE
    ru.Ride_ID IN (
    SELECT rp1.Ride_ID
    FROM RidePlace as rp1
    WHERE rp1.Place_ID=p.Message_ID
    )
    ) AS RidersCount
    FROM
    Message49 as p

    LEFT JOIN
    RidePlace rp2 ON rp2.Place_ID=p.Message_ID
    LEFT JOIN
    RideUser ru1 ON ru1.User_ID=1 AND ru1.Ride_ID=rp2.Ride_ID

    LEFT JOIN
    RidePlace rp3 ON rp3.Place_ID=p.Message_ID
    LEFT JOIN
    RideUser ru2 ON ru2.User_ID=4561 AND ru2.Ride_ID=rp3.Ride_ID

    WHERE
    ru1.User_ID=1 AND
    ru2.User_ID=4561
    LIMIT 0,10



    Распиши именно на этот запрос легенду, а то имена таблиц у тебя не соответствуют тем, которые ты приводил в первом посте
    То есть, что ты вообще хотел выбрать распиши (типа так как в первом посте, но только для этого sql)
    adw/0

Пожалуйста, авторизуйтесь, чтобы написать комментарий!