Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [3]  Все   Вниз
  Печать  
Автор Тема: Нестандартный вывод записей из таблицы  (Прочитано 39253 раз)
0 Пользователей и 5 Гостей смотрят эту тему.
nerik
Интересующийся

ru
Offline Offline

« Ответ #60 : 02-04-2013 04:27 » 

Dimka, не хочу спорить.

Лишь прошу автора топика протестировать все три варианта запроса и выдать все возможные параметры выполнения: время, ЦП, IO
с указанием кол-ва записей в исходной таблице (это немало важный показатель)

уже самому интересно кто прав, а то может точно мне надо пойти учить мат.часть Улыбаюсь

Ваш запрос интересен, но в моей БД исключены дублирование записей в таблице prds. Я использую сейчас оба запроса (от RXL и Dimka). По моим тестам запрос RXL выигрывает в скорости в разы. Но второй запрос мне нужен для вывода других данных. По Вашей просьбе вот результаты запросов:) В таблице 1090 записей.

select t1.date `from`, t2.date `to`, t2.id_work `id_work`
from (select 0 n union select 1 union select 2) seq, prds t1, prds t2  
where t1.id_work=t2.id_work and t2.date=t1.date+interval seq.n day and t1.allo>0 and t2.allo>0
group by t2.date, t2.id_work having count(t2.date)=3;
#Отображает строки 0 - 29 ( 495 всего, Запрос занял 0.0240 сек.)

select min(t2.date) `from`, max(t2.date) `to`, t2.id_work `id_work`
from prds t1 join prds t2 on t1.allo>0 and t2.allo>0 and t2.date between t1.date and date_add(t1.date,interval 2 day)
group by t1.date, t2.id_work having count(distinct t2.date)=3;
#Отображает строки 0 - 29 ( 495 всего, Запрос занял 0.2913 сек.)

select t.date+interval seq.n-2 day `from`, t.date+interval seq.n day `to`, t.id_work `id_work`
from prds t, (select 0 n union select 1 union select 2) seq
group by t.date+interval seq.n-2 day, t.date+interval seq.n day, t.id_work
having sum(case when t.allo=0 then 1 else 0 end)=0 and count(distinct t.date)=3;
#Отображает строки 0 - 29 ( 495 всего, Запрос занял 0.0146 сек.)

Получается третий вариант побыстрее будет, хотя в продакшене при добавлении других частей запроса (другие условия), почему то проигрывает, но это буду уже сам разбираться)
Тут ещё используется только один раз таблица с периодами. и возможна защита от повторения записей.
Буду исследовать запрос.
HandKot, спасибо).
« Последнее редактирование: 02-04-2013 06:19 от nerik » Записан
HandKot
Молодой специалист

ru
Offline Offline

« Ответ #61 : 02-04-2013 05:37 » 

Цитата: Dimka
HandKot, я тебе из без тестов скажу, что по времени, загрузке и вводу/выводу запрос с соединением таблицы с самой собой
будет работать медленнее просто потому, что во второй таблице больше записей. Его преимущество перед схемой решения RXL
в универсальности за счёт параметра, а преимущество подхода RXL в скорости.
Поэтому если ты на что-то надеешься, то сравнивай с вариантом RXL.

Дабы быть непредвзятым во всем, то сравнивал все три варианта
Исходные данные:
Таблица - 2046 записей
id_work - постоянный

1 случай: allo - всегда больше 0, кол-во периодов 2046
Dimka - 3272 ms
RXL - 50 ms
HandKot - 8ms

2 случай: allo - каждый 10 равен 0, кол-во периодов 1433
Dimka - 2481 ms
RXL - 60 ms
HandKot - 8 ms

3 случай: allo - всегда равен 0, кол-во периодов 0
Dimka - 2 ms
RXL - 1 ms
HandKot - 7 ms

все эксперименты проводил тут http://sqlfiddle.com/#!2/042f9/1/0

эти данные подтвердил и автор топика (пост выше)

ЗЫЖ могу предположить, что на некотором наборе данных, мой запрос будет либо проигрывать в скорости, либо выдавать неверный результат, либо и то и другое. Но приемущество его в том, что он всегда использует всего один скан таблицы с постоянным временем исполнения, тогда как вариант от RLX  использует 2 скана, по поводу Вашего варианта, то там сложно сказать кол-во сканов (оно зависит от распределения данных по таблице)

ЗЗЫЖ
Цитата: Dimka
Запятая во from - это cross join (полное декартово произведение) в отличие от inner join в остальных примерах, где результаты этого декартова произведения подвергаются обработке горизонтальным фильтром.

это понятно, но надо учитывать и кол-во получаемых строк. Inner Join хорош когда в условии соединения идет знак равенства (применяется hash match). При неопределенном условии (операторы больше и меньше) мы , скорее всего перейдем на loop join (при большом кол-ве строк, ну очень затратный метод)
Цитата: Dimka
Т.е. у тебя на группировку попадает больше групп, чем нужно. Более того, твой запрос, в котором вариации распространены и на to, и на from, порождает больше групп в штуках (хотя и эквивалентных друг другу дубликатов), чем варианты с одной фиксированной опорной датой и другой вариативной (где дубликатов вовсе нет). А ведь эти лишние группы ещё надо убирать.

кол-ве групп будет при таблице в 1000 строк = cross join -> 1004 групп на 3000 строках с кучей дубликатов. Агрегатные функции одни из самых быстрых в БД


в общем как-то так
Записан

I Have Nine Lives You Have One Only
THINK!
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #62 : 02-04-2013 05:40 » 

Цитата
Запрос занял 0.0240 сек.

На малых значениях это не показатель. Поищи в мануале «query profile». Это позволит делать более точную диагностику.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #63 : 02-04-2013 11:39 » 

Индексы и их эффективность тоже важны при выборе между поиском по хэш и перебором. Так что индексы следует описывать, равно, как и знать характер данных.

Цитата: HandKot
Исходные данные:
Таблица - 2046 записей
id_work - постоянный

1 случай: allo - всегда больше 0, кол-во периодов 2046
А будто бы должно быть меньше, чем исходных записей.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
HandKot
Молодой специалист

ru
Offline Offline

« Ответ #64 : 02-04-2013 12:48 » new

Цитата
А будто бы должно быть меньше, чем исходных записей.
точно описался, в таблице 2048.
если перейти по ссылке, то там есть все изыскания (только копируйте ее полностью)
Записан

I Have Nine Lives You Have One Only
THINK!
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #65 : 02-04-2013 14:11 » 

HandKot, не ходил: пусть автор темы ходит, если ему охота.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: 1 2 [3]  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines