Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Время выполнения запроса 
V
    Опции темы
Bulat
Дата 21.7.2008, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: нет
Всего: 57



Код

    SELECT
    sum(rs.hits) as hits,
    sum(rs.hits * rs.price * o.percent/100)/1000 AS hits_amount,
    if (o.person = o1.person, 0, 1) as 'co_author'
    FROM ownership o
    LEFT JOIN read_stats rs ON rs.art = o.art #key
        LEFT JOIN ownership o1 ON o1.art = o.art #key
        JOIN copyrights c ON c.person = o1.person #key
    WHERE o.person = ? #int - key
        AND o.relation = ? #int
        AND rs.time >= ?  #datetime - key
        AND rs.time <= ?  #datetime - key
        AND c.user = ?  #int - key
    AND o.percent != 0 AND o1.percent != 0
      GROUP BY co_author


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

P.S. Есть аналогичные запросы, основное отличие в использовании вместо таблицы read_stats другой и разве что меньшее количество строк(т.е. в read_stats могут просуммироватся данные до нескольких десятков тысяч строк, сотня тысяч, а в аналогичных запросах - несколько десятков, сотня). Т.е. может ли количество строк в данном случае замедлять запрос?? 


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
Kesh
Дата 21.7.2008, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2488
Регистрация: 31.7.2002
Где: Германия, Saarbrü cken

Репутация: 15
Всего: 54



Конечно, у вас же помимо выборки еще умножение - деление удет...
Будет чуть-чуть быстрее, если o.percent/100)/1000 -> o.percent*0.000001


--------------------
user posted image
PM MAIL WWW ICQ Skype   Вверх
skyboy
Дата 21.7.2008, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(Kesh @  21.7.2008,  16:06 Найти цитируемый пост)
Будет чуть-чуть быстрее, если o.percent/100)/1000 -> o.percent*0.000001 

в смысле, вынести константу за вызов аргегирующей функции sum.
это раз.
заменить if на условие where + union.
или вообще на стороне клиента делать if.
как много строк в таблицах, на которые делается left join?
PM MAIL   Вверх
Bulat
Дата 21.7.2008, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: нет
Всего: 57



Цитата(skyboy @  21.7.2008,  18:16 Найти цитируемый пост)

заменить if на условие where + union.
или вообще на стороне клиента делать if.


Не очень соображу как расписать запрос в таком виде.

т.е. в таблице read_stats хранится определенная статистика по книгам. У каждой книги может быть один или несколько авторов, что отражается в таблице ownership. Мне нужно получить статистику из таблицы read_stats для определенного автора, но если в эту статистику входят книги, где есть соавторы, нужно одной строкой получить и данные по тем статистическим данным, где есть соавторы.

Надеюсь не слишком запутанно smile

Т.е. ownership(данные по конкретному автору) -> read_stats(статистика по книгам) -> ownership1(перебираю соавторов если они есть) ... и соотв. внизу группирую вся статистика для конкретного автора, и статистика для соавторов(часть статистика для конкретного автора)


Цитата(skyboy @  21.7.2008,  18:16 Найти цитируемый пост)
как много строк в таблицах, на которые делается left join? 


В read_stats несколько миллионов наберется, а в остальных от нескольких сотен, до пару десятков тысяч(но это уже не много).


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
skyboy
Дата 21.7.2008, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(Bulat @  21.7.2008,  17:55 Найти цитируемый пост)
Не очень соображу как расписать запрос в таком виде.

запрос 
Код

SELECT if(`field` = 3, 0, 1)
FROM `table`

может быть представлен в виде
Код

SELECT 0
FROM `table`
WHERE `field` = 3
UNION ALL
SELECT 0
FROM `table`
WHERE `field` <> 3

Цитата(Bulat @  21.7.2008,  17:55 Найти цитируемый пост)
но это уже не много

почему же? smile
у тебя же left join. значит, происходит практически перемножение.
т.е. результат будет порядка:
10^6 * 10^4 * 10^2 * 10^2 == 10^14
это даже не миллиарды записей.
и по ним ты делаешь группировку.... smile
посмотри, сколько записей у тебя возвращает запрос без "group by"
PM MAIL   Вверх
Bulat
Дата 22.7.2008, 09:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: нет
Всего: 57



skyboy, Нет, нет, нет

Код

    SELECT
    sum(rs.hits) as hits,
    sum(rs.hits * rs.price * o.percent*0.000001) AS hits_amount,
    0 as 'co_author'
    FROM ownership o
    LEFT JOIN read_stats rs ON rs.art = o.art 
        LEFT JOIN ownership o1 ON o1.art = o.art
        JOIN copyrights c ON c.person = o1.person 
    WHERE o.person = ? AND o.relation = ?    AND rs.time >= ? AND rs.time <= ?    AND c.user = ?
    AND o.percent != 0 AND o1.percent != 0 AND o.person = o1.person
    UNION ALL
    SELECT
    sum(rs.hits) as hits,
    sum(rs.hits * rs.price * o.percent*0.000001) AS hits_amount,
    1 as 'co_author'
    FROM ownership o
    LEFT JOIN read_stats rs ON rs.art = o.art 
        LEFT JOIN ownership o1 ON o1.art = o.art
        JOIN copyrights c ON c.person = o1.person 
    WHERE o.person = ? AND o.relation = ?    AND rs.time >= ? AND rs.time <= ?    AND c.user = ?
    AND o.percent != 0 AND o1.percent != 0 AND o.person <> o1.person


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

Но это еще не все. smile

Код

    select
    p.s_full_name as s_author_for_stat, p.id as person_id, p.lvl, o.relation,
    sum(rs.hits) as hits,
    sum(rs.hits * rs.price * o.percent/100)/1000 AS hits_amount
    from copyrights c
    left join    persons p on c.person=p.id
    left join ownership o on o.person=p.id
    left join read_stats rs ON rs.time >= ? AND rs.time <= ? and rs.art=o.art
    where    c.user=?
    group by p.id, o.relation
    order by p.s_full_name asc


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

Больше я ни с чем не могу связать. Кстати последний запрос, который сейчас на боевом сервере работает быстро, у меня отрабатывает тоже довольно долго smile




--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
ТоляМБА
Дата 22.7.2008, 09:32 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Котэ
***


Профиль
Группа: Завсегдатай
Сообщений: 1607
Регистрация: 15.12.2004

Репутация: 10
Всего: 252



Цитата(Bulat @  22.7.2008,  12:25 Найти цитируемый пост)
    select    p.s_full_name as s_author_for_stat, p.id as person_id, p.lvl, o.relation,
    sum(rs.hits) as hits,    sum(rs.hits * rs.price * o.percent/100)/1000 AS hits_amount    
from copyrights c    
left join    persons p on c.person=p.id    
left join ownership o on o.person=p.id    
left join read_stats rs ON rs.time >= ? AND rs.time <= ? and rs.art=o.art    
where    c.user=?    group by p.id, o.relation    order by p.s_full_name asc

Разве это рабочий запрос? Ведь выделенные красным поля не включены в Group by
PM   Вверх
skyboy
Дата 22.7.2008, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



не надо делать так
Цитата(Bulat @  22.7.2008,  08:25 Найти цитируемый пост)
sum(rs.hits * rs.price * o.percent*0.000001)

надо делать так:
Код

sum(rs.hits * rs.price * o.percent)*0.000001

дамп структуры БД и хранимку, которая заполняла бы БД рандомными значениями можешь выложить?
PM MAIL   Вверх
Bulat
Дата 22.7.2008, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: нет
Всего: 57



Цитата(skyboy @  22.7.2008,  09:34 Найти цитируемый пост)
не надо делать так

надо делать так:


Я делал и так, и так. Все равно довольно медленно smile

Цитата(skyboy @  22.7.2008,  09:34 Найти цитируемый пост)
дамп структуры БД и хранимку, которая заполняла бы БД рандомными значениями можешь выложить? 


Вот что могу прям счас выложить. Знаю, не много, но есть определенные "но", да и занят пока другой срочной работой.

Код

| read_stats | CREATE TABLE `read_stats` (
  `art` int(10) unsigned NOT NULL default '2',
  `place` smallint(5) unsigned NOT NULL default '0',
  `time` date default NULL,
  `hits` smallint(5) unsigned NOT NULL default '0',
  `processed` smallint(5) unsigned NOT NULL default '0',
  `price` tinyint(3) unsigned NOT NULL default '30',
  UNIQUE KEY `art` (`art`,`place`,`time`,`processed`),
  KEY `non_proc` (`processed`,`art`),
  KEY `read_stats_ibfk_2` (`place`),
  KEY `time` (`time`),
  CONSTRAINT `read_stats_ibfk_1` FOREIGN KEY (`art`) REFERENCES `arts` (`id`) ON
 DELETE CASCADE,
  CONSTRAINT `read_stats_ibfk_2` FOREIGN KEY (`place`) REFERENCES `read_places`
(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

| ownership | CREATE TABLE `ownership` (
  `art` int(10) unsigned NOT NULL default '0',
  `person` int(10) unsigned NOT NULL default '0',
  `relation` tinyint(3) unsigned NOT NULL default '0',
  `percent` tinyint(3) unsigned default NULL,
  KEY `art` (`art`),
  KEY `person` (`person`),
  KEY `relation` (`relation`),
  CONSTRAINT `ownership_ibfk_1` FOREIGN KEY (`art`) REFERENCES `arts` (`id`) ON
DELETE CASCADE,
  CONSTRAINT `ownership_ibfk_2` FOREIGN KEY (`person`) REFERENCES `persons` (`id
`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

| copyrights | CREATE TABLE `copyrights` (
  `user` int(10) unsigned NOT NULL default '0',
  `person` int(10) unsigned NOT NULL default '0',
  `sale_part` tinyint(3) unsigned NOT NULL default '33',
  `read_price` tinyint(3) unsigned NOT NULL default '30',
  UNIQUE KEY `person_2` (`person`),
  KEY `user` (`user`),
  CONSTRAINT `copyrights_ibfk_1` FOREIGN KEY (`user`) REFERENCES `users` (`id`),

  CONSTRAINT `copyrights_ibfk_2` FOREIGN KEY (`person`) REFERENCES `persons` (`i
d`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |


ТоляМБА, "политика" такая. smile Если бы она была чуть иная, скорее всего с медленно работающими запросами, у которых хороший explain я бы вряд ли столкнулся. smile


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
skyboy
Дата 22.7.2008, 10:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(Bulat @  22.7.2008,  09:41 Найти цитируемый пост)
 Знаю, не много

мягко говоря, не хватает таблицы persons.
и хоть по 2-3 записи на таблицу.
PM MAIL   Вверх
Bulat
Дата 22.7.2008, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: нет
Всего: 57



Цитата(skyboy @  22.7.2008,  10:50 Найти цитируемый пост)
мягко говоря, не хватает таблицы persons.


сорри

Код

| persons | CREATE TABLE `persons` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `alphabet` char(1) default NULL,
  `s_first_name` varchar(255) default NULL,
  `s_middle_name` varchar(255) default NULL,
  `s_last_name` varchar(255) default NULL,
  `s_full_name` varchar(255) default NULL,
  `s_banking` text,
  `s_phone` varchar(50) default NULL,
  `s_email` varchar(50) default NULL,
  `s_www` varchar(50) default NULL,
  `text_description` text,
  `ext_id` varchar(100) default NULL,
  `unchecked` tinyint(3) unsigned NOT NULL default '0',
  `s_gps` varchar(50) default NULL,
  `birth_year` int(11) default NULL,
  `s_adress` varchar(250) default NULL,
  `on_sale` smallint(5) unsigned NOT NULL default '0',
  `owner` int(10) unsigned default NULL,
  `lvl` tinyint(4) NOT NULL default '0',
  `top_genres` varchar(30) default NULL,
  PRIMARY KEY  (`id`),
  KEY `alphabet` (`alphabet`),
  KEY `owner` (`owner`),
  CONSTRAINT `persons_ibfk_1` FOREIGN KEY (`owner`) REFERENCES `users` (`id`) ON
 DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |



А вот записи, реальные на вряд ли. smile


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
skyboy
Дата 22.7.2008, 11:56 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(Bulat @  22.7.2008,  10:13 Найти цитируемый пост)
А вот записи, реальные на вряд ли

нафиг мне реальные данные?
во все текстовые поля запихни один символ(произвольный).
timestamp - рандомное число.
не заниматься же мне ещё и анализом структуры БД, чтоб заполнить хотя бы десятком записей с корректными значениями, верно?
PM MAIL   Вверх
sTa1kEr
Дата 22.7.2008, 16:01 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 7
Всего: 146



Цитата(skyboy @  21.7.2008,  19:16 Найти цитируемый пост)
заменить if на условие where + union.

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

ТоляМБА, совершенно верное замечание. Хоть MySQL и не выдает ошибку, выборка полей не сгруппированных и не использующих агрегатные функции - полностью бессмысленна и непредсказуема.

Bulat, попробуйте постепенно упрощать запрос, убирая по одному элементу из запроса. 
Так же выполните запрос SHOW STATUS, возможно серверу просто не хватает места для кеширования всех индексов, используемых в запросе. Попробуйте поиграться с параметрами сервера Tuning Server Parameters и InnoDB Performance Tuning Tips
PM MAIL   Вверх
skyboy
Дата 22.7.2008, 16:11 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



sTa1kEr, в случае с двумя запросами уходит одна из группировок как раз по этому  результату "атомарной логической операции". так что даже не знаю...

Добавлено через 1 минуту и 11 секунд
Цитата(sTa1kEr @  22.7.2008,  15:01 Найти цитируемый пост)
Плюс ко всему будет дублирование запроса

если есть вариант: подзапрос или union что выберешь ты?
кстати говоря, индекс применяется при использовании функции(оператора) if?
PM MAIL   Вверх
sTa1kEr
Дата 22.7.2008, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 7
Всего: 146



Цитата(skyboy @  22.7.2008,  17:11 Найти цитируемый пост)
в случае с двумя запросами уходит одна из группировок

Прошу прощенья, не заметил группировку. В этом случае, я думаю, будет по сути примерно одно и тоже.
Цитата(skyboy @  22.7.2008,  17:11 Найти цитируемый пост)
если есть вариант: подзапрос или union что выберешь ты?

При чем тут подзапрос? Я имел ввиду то, что операция if() сама по себе ничего не стоит.
Цитата(skyboy @  22.7.2008,  17:11 Найти цитируемый пост)
кстати говоря, индекс применяется при использовании функции(оператора) if? 

Какой индекс в поле выборки?
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.1061 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.