Конференция "Базы" » select неповторяющихся записей [D7, IB6.x]
 
  • dest81 (14.12.08 19:11) [0]
    Подскажите как сделать оптимальный запрос для такой таблицы

    id         date       name     total
    1        20.08.08   petya       20
    34      20.08.08   petya       35
    3        22.08.08   petya       20
    44      22.08.08   petya       60

    что б он выдал  неповторимые даты с максимальным id +name+total:

    id         date       name     total
    34      20.08.08   petya       35
    44      22.08.08   petya       60
  • palva © (14.12.08 19:43) [1]
    Непонятен вопрос. Во-первых как вы собираетесь складывать name и total, во-вторых что выдавать, когда в двух стоках для данной даты id+total максимально и одинаково, а name различается? Две строчки выдавать? Возможно, если вы потрудитесь и правильно сформируете вопрос, то ответ сразу будет ясен.
  • Правильный$Вася (14.12.08 19:55) [2]
    а если у максимального ID будет немаксимальный TOTAL или наоборот?
    и что значит максимальный NAME?
  • dest81 (14.12.08 20:09) [3]
    Извините я неправильно выразился

    > что б он выдал  неповторимые даты с максимальным id +name+total

    может так будет понятно:
    что б он выдал  неповторимые даты с максимальным id и поля name и total которые принадлежат записи с номером id
    ЗАРАНЕЕ СПАСИБО!!!
  • palva © (14.12.08 20:41) [4]
    Может вложенный запрос прокатит? В MS SQL такое работает:
    SELECT * FROM table1 WHERE id IN (SELECT MAX(id) FROM table1 GROUP BY date)

  • dest81 (14.12.08 21:20) [5]
    Спасибо! Работает только очень медленно, может есть еще какой-то способ?
  • palva © (14.12.08 21:34) [6]
    Если нету, то создать индекс по id и date. Должно ускорить.
  • Sergey13 © (15.12.08 09:37) [7]
    > [6] palva ©   (14.12.08 21:34)
    > то создать индекс по id и date

    В этом случае, ИМХО, логичней будет date+id.
  • ANB (15.12.08 14:06) [8]

    > В этом случае, ИМХО, логичней будет date+id.

    Не поможет. В наружном запросе надо по ID, во внутреннем - по дате.

    Так что прав палва.

    Хотя, если в таблице записей не много - должно и так работать. Но это уже от СУБД зависит.
  • Sergey13 © (15.12.08 14:47) [9]
    > [8] ANB   (15.12.08 14:06)
    > Не поможет.
    Не факт. Пробовать надо. Тут задача, ИМХО, ускорить подзапрос, а для этого желательно заставить его работать без таблицы, с одним индексом. С моим вариантом индекса это кажется будет проще. Но... пробовать надо.
  • ANB (15.12.08 15:21) [10]

    > Sergey13 ©   (15.12.08 14:47) [9]

    Можно даже не пробовать.

    date+id - не сможет использоваться в основном запросе.

    Впрочем, на оракле я бы вообще выбросил индексы и сделал на фулл-сканах. Был бы самый шустрый вариант.
  • Sergey13 © (15.12.08 15:40) [11]
    > [10] ANB   (15.12.08 15:21)
    > date+id - не сможет использоваться в основном запросе.

    Почему?
  • ANB (15.12.08 15:46) [12]
    Потому что поиск только по ID, а ID в составном индексе на 2-м месте. Значит не может использоваться. Чтобы использовался - нужно условие и по дате.
  • Sergey13 © (15.12.08 15:49) [13]
    > [12] ANB   (15.12.08 15:46)

    Я говорю про подзапрос. Он при правильно подобранном индексе будет (должен) выполняться без участия таблицы.
    А внешний запрос тут так и так пойдет фулсканом, ИМХО.
  • ANB (15.12.08 15:54) [14]

    > А внешний запрос тут так и так пойдет фулсканом, ИМХО.

    Если будет индекс по ID - зачем ему идти фуллсканом.

    Вообще тут надо смотреть на количество ID в одной дате. Если много (больше 100) - надо цеплять индексы. Если 2-3 - однозначно фуллсканн с хэш-джойном будет шустрее. Если что то среднее - надо пробовать так и эдак.
  • ANB (15.12.08 15:56) [15]
    Для подзапроса то действительно, будет выгоднее дата+ID.
    Если вообще индекс будет нужен. В таблицу то все равно лезть.
  • Sergey13 © (15.12.08 15:59) [16]
    > [14] ANB   (15.12.08 15:54)

    Согласен, про фул скан я кажется погорячился, но по любому для подзапроса индексом стОит поиграться. Тем более, что по ИД он наверное так и так есть.
    Только автору эта тема видимо уже не интересна.
  • Petr V. Abramov © (16.12.08 01:36) [17]
    не нужен тут индекс, вреден, нужно что-то типа hash или merge join
  • Кщд (16.12.08 07:11) [18]
    >ANB   (15.12.08 15:56) [15]
    >Для подзапроса то действительно, будет выгоднее дата+ID.
    по такому индексу будет FFS - чем это лучше table access full в данном случае?

    >Petr V. Abramov ©   (16.12.08 01:36) [17]
    >не нужен тут индекс, вреден, нужно что-то типа hash или merge join
    в oracle, например, это записывается так(хинты - для того, чтобы подчеркнуть логику, согласно которой сервер обрабатывает запрос. более, чем вероятно, что оптимизатор сам построит именно этот план):

    select /*+ ordered use_nl(t t2) */
          t2.*
    from (select max(t2.id) id
        from table1 t2
        group by t2.dt
        ) t
          join table1 t2
            on t.id = t2.id


    в (t) индекс, действительно, ни к чему, но по ID должен быть, т.к. в этом случае получим вполне уместный NL, где в качестве ведущей таблицы выступает (t) и данные из (t2) берутся строго по index unique scan.
  • ANB (16.12.08 12:56) [19]

    > по такому индексу будет FFS - чем это лучше table access
    > full в данном случае?

    FFS пошустрее будет. Проверялось.
    Но. Если нужен только один отчет по такому индексу и больше он не нужен нигде, то фулл-сканн однозначно лучше. Согласен.

    А вот NL - это, как я уже говорил, зависит от количества ID на одну дату. HASH может оказаться лучше.
  • Кщд (16.12.08 13:11) [20]
    >ANB   (16.12.08 12:56) [19]
    >FFS пошустрее будет. Проверялось.
    в данном случае(индекс по date + id) придется пройти все листовые блоки, а т.к. такой индекс(по причине уникальности) содержит столько листовых элементов, сколько записей в table1(считаем, что id и date - not nullable).
    пошустрее - это да, согласен, т.к. будет читать данные по порядку по листам индекса, а не метаться между блоками таблицы.
    однако, вовсе не уверен, что это даст радикальный прирост по скорости).

    >А вот NL - это, как я уже говорил, зависит от количества ID на одну дату. HASH может оказаться лучше.
    здесь же NL будет всегда [b]не хуже[/b], hash join для t и t2
  • ANB (16.12.08 17:13) [21]

    > здесь же NL будет всегда [b]не хуже[/b], hash join для t
    > и t2

    Пробовать надо.


    > это даст радикальный прирост по скорости

    Согласен.
    Не больше чем в 1.5-2 раза. Во всяком случае СОЗДАВАТЬ индекс для отчета смысла нету. Если уже есть - то можно использовать, будет немного шустрее.
  • MsGuns © (16.12.08 22:26) [22]
    >Кщд   (16.12.08 07:11) [18]

    А что, ИБ уже научили понимать вложеные запросы ?
  • Кщд (17.12.08 11:24) [23]
    MsGuns ©   (16.12.08 22:26) [22]
    >А что, ИБ уже научили понимать вложеные запросы ?
    отдельно оговаривалось, что речь об oracle
    обсуждение началось с того, что использование индексов в данном случае нерационально

    >SELECT * FROM table1 WHERE id IN (SELECT MAX(id) FROM table1 GROUP BY date)
    речь шла об этом и только об этом запросе, а его IB6 должен бы понять

    в моем примере (Кщд   (16.12.08 07:11) [18]) запрос был написан в форме, в которую указанный выше select будет преобразован oracle'ом при построении плана
  • Petr V. Abramov © (17.12.08 23:29) [24]

    > отдельно оговаривалось, что речь об oracle

    тогда
    select first_value("date") over (order by id,name,total)
    from хрен_знает
  • Кщд (18.12.08 07:43) [25]
    >Petr V. Abramov ©   (17.12.08 23:29) [24]
    >тогда
    >select first_value("date") over (order by id,name,total)
    >from хрен_знает
    так мы получим ВСЕ данные из "хрен_знает" + last_value(id) over (partition by "date" order by id)
  • Petr V. Abramov © (18.12.08 13:47) [26]

    > Кщд   (18.12.08 07:43) [25]

    я идею написал, понятно, что надо еще чуть-чуть букв :)
 
Конференция "Базы" » select неповторяющихся записей [D7, IB6.x]
Есть новые Нет новых   [134477   +39][b:0][p:0.001]