|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Добрый день! Использую Firebird 2.5. Есть таблица (ID, TIMESTAMP, CLIENT_ID). Нужно выбрать максимальные TIMESTAMP с группировкой по CLIENT_ID. Простой запрос: select client_id, max(timestamp) from tbl group by client_id Проблема в том, что судя по анализатору, при выполнении такого запроса просматриваются все записи таблицы. Пробовал создавать различные индексы по client_id, timestamp в разных сочетаниях и сортировках. Подскажите, может как-то переделать этот запрос или еще какой способ..? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 10:33 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C при выполнении такого запроса просматриваются все записи таблицы. А что не так? Вы же ищете максимальные значения из всей таблицы. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 10:37 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Мне кааца, что нужен индекс по убыванию по значениям ID и тайм-штампа ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 10:39 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
o_v_a, пробовал, всё равно извлекает все записи ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 10:41 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
SQL2008, если, например, сделать просто select max(timestamp) from tbl, то потребуется чтение одной записи по индексу timestamp. Хотя максимум по всей таблице ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 10:43 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C, Ваши претензии не понятны. У Вас же нет фильтра. Значит все записи просматриваются. И индексы не причём. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 10:50 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
KreatorXXI, возможно, вы правы. Но может этот запрос записать как-то по-другому? Вот если я пишу select max(timestamp) from tbl where client_id=1, то он отрабатывает за одно чтение. Если у меня сто клиентов, то,теоретически, требуется сто чтений. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 11:01 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C, и что? 100 это много? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 11:05 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr Cвозможно, вы правы. Но может этот запрос записать как-то по-другому? не "возможно", а он прав. Если вы перебираете все элементы множества, то самым эффективным будет НЕ использование индекса в данном случае. Потому что если сюда присунуть индекс, чтения из него будут лишними. Индекс имеет смысл только если выбирается часть записей из таблицы. Соответственно, этот запрос "по другому" в данном случае переписывать нет никакого смысла. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 11:11 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C Вот если я пишу select max(timestamp) from tbl where client_id=1, то он отрабатывает за одно чтение. Если у меня сто клиентов, то,теоретически, требуется сто чтений. Я понял чего вам хочется :) Мы можете так сделать, но только в случае когда вам точно известно ваше максимальное значение timestamp! Поставьте на это поле индекс и будет вам счастье. В вашем примере вы точно знаете какой client_id вам нужен. От этого он и читает только одну запись. А вот если сделаете Код: sql 1.
то получите тот же самый full scan table ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 11:25 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
kdv, Хорошо. Согласен. Забудем про этот запрос. Подскажите, как извлечь максимумы timestamp по каждому клиенту? Делать по одному запросу на каждого клиента? Это работает, при этом будет число чтений, соответствующих числу клиентов, что очень даже быстро. Но неужели нельзя сделать эту выборку одним запросом? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 11:27 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C Подскажите, как извлечь максимумы timestamp по каждому клиенту? Если без перебора всех значений, то только научив БД экстрасенсорным способностям. Не верите? Попробуйте вытащить из мешка картошки самую тяжелую картофелину без перебора всех остальных. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 11:34 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C, какую-то вы фигню пишите про чтения. Давай сюда реальную статистику и план для запроса Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 11:37 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
SQL2008Alexandr C Подскажите, как извлечь максимумы timestamp по каждому клиенту? Если без перебора всех значений, то только научив БД экстрасенсорным способностям. Не верите? Попробуйте вытащить из мешка картошки самую тяжелую картофелину без перебора всех остальных. Ну, например, select max(timestamp) from tbl выполняется за одно чтение. Не верите? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 11:38 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C, Попробуйте через вторую таблицу "Клиентов", типа: Код: sql 1. 2. 3. 4. 5. 6.
Назвать поле "timestamp" тоже сильный ход. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 11:39 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr CSQL2008пропущено... Если без перебора всех значений, то только научив БД экстрасенсорным способностям. Не верите? Попробуйте вытащить из мешка картошки самую тяжелую картофелину без перебора всех остальных. Ну, например, select max(timestamp) from tbl выполняется за одно чтение. Не верите? Не верю. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 11:47 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
KreatorXXIAlexandr C, Попробуйте через вторую таблицу "Клиентов", типа: Код: sql 1. 2. 3. 4. 5. 6.
Назвать поле "timestamp" тоже сильный ход. timestamp - это не реальное имя столбца. Просто чтобы понимали, о чем речь. Спасибо. Сейчас попробую. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 11:47 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
KreatorXXIAlexandr C, Попробуйте через вторую таблицу "Клиентов", типа: Код: sql 1. 2. 3. 4. 5. 6.
Назвать поле "timestamp" тоже сильный ход. Огромное Вам спасибо! Это то, что нужно! ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 12:02 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Симонов ДенисAlexandr C, какую-то вы фигню пишите про чтения. Давай сюда реальную статистику и план для запроса Код: sql 1.
Прилагаю скриншот. Посмотрите. Может можно с этим что-нибудь сделать. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 12:59 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C, а текст скопировать никак? Обязательно надо скриншотами бомбардировать? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 13:04 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Симонов ДенисAlexandr C, а текст скопировать никак? Обязательно надо скриншотами бомбардировать? Извините, я не знал что именно копировать. А исправлять свои сообщения можно? Я бы переделал. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 13:13 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C, Если есть время, можно поэкспериментировать так. Поставить явное условие "where", а в нём какую-нибудь фигню типа "client_id=client_id+0". Или всякую другую фигню. Типа планировщик при каком-то условии сменит план. Только принимать мои слова на веру не рекомендую. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 13:14 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
KreatorXXI, попробовал. всё тоже. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 13:22 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
KreatorXXI, не сменит ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 13:24 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C, а что не нравится-то? Запрос select max(tstamp) from tbl group by client_id имеет план, как видим PLAN (TBL ORDER TBL_IDX3) Это значит, что оптимизатор решает встать на индекс TBL_IDX3, ехать по ключам, перебирая все записи (раз условия фильтрации нет), и выдавая клиенту только max(tstamp) значения. Эффект от плана TABLE ORDER INDEX известен - первые записи выдаются достаточно быстро, а дальше будут прыжки по страницам записей в поисках записей в соответствии с порядком ключей в индексе. Так что, в том гриде надо бы еще нажать ctrl-end (или FetchAll) для получения верной картины. Быстрее было бы прибить индекс TBL_IDX3, или написать group by client_id+0, чтобы было PLAN SORT... http://www.ibase.ru/dataaccesspaths/ ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 13:45 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
kdv, Прибил индекс, результат: Plan PLAN SORT ((TBL NATURAL)) ------ Performance info ------ Prepare time = 16ms Execute time = 562ms Avg fetch time = 562.00 ms Current memory = 35 662 976 Max memory = 57 806 088 Memory buffers = 2 048 Reads from disk to cache = 934 Writes from cache to disk = 0 Fetches from cache = 771 822 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 13:52 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C, ну вот. Как видишь быстрее оказалось ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 13:59 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Симонов Денис, Вот результаты запроса, предложенного KreatorXXI: Plan PLAN (B ORDER TBL_IDX2 INDEX (TBL_IDX1)) PLAN (A NATURAL) ------ Performance info ------ Prepare time = 15ms Execute time = 47ms Avg fetch time = 15.67 ms Current memory = 35 781 144 Max memory = 57 806 088 Memory buffers = 2 048 Reads from disk to cache = 30 Writes from cache to disk = 0 Fetches from cache = 506 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 14:10 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C, это ты fetchAll не сделал. Запрос KreatorXXI делает совсем дохрена лишнего. Можно считать его вариант извратом :-) Обрамление внутреннего запроса внешним никогда не даст выигрыша, это нонсенс. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 14:16 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C, у вас там что 3 клиента всего? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 14:19 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Симонов ДенисAlexandr C, у вас там что 3 клиента всего? число записей таблицы clients << числа записей таблицы tbl. Ну это и понятно, одно дело таблица справочника клиентов, а другое, например, записи об их заказах. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 14:28 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
kdvAlexandr C, это ты fetchAll не сделал. Запрос KreatorXXI делает совсем дохрена лишнего. Можно считать его вариант извратом :-) Обрамление внутреннего запроса внешним никогда не даст выигрыша, это нонсенс. Нет, это был fetchAll ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 14:30 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
kdv, забавно, но это воспроизводится DDL Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
Код: sql 1. 2. 3.
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.
... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 14:54 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Такое впечатление, что каждый в этом топике обсуждает что-то своё. В итоге всё сводится к отличию планов PLAN (TBL1 ORDER TBL_IDX1) PLAN (TBL1 ORDER TBL_IDX1 INDEX (TBL_IDX2)) Сейчас ломать голову не буду, но вроде был более простой способ выбрать второй, чем вложенный запрос. Или даже PLAN (TBL1 ORDER TBL_IDX1 INDEX (TBL_IDX1)) для одного композита. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 15:05 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
WildSery, а не хватается композит в group by + max (даже если он DESC) И +0 для первого запроса не помогает ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 15:10 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
kdvAlexandr C, это ты fetchAll не сделал. Запрос KreatorXXI делает совсем дохрена лишнего. Можно считать его вариант извратом :-) Обрамление внутреннего запроса внешним никогда не даст выигрыша, это нонсенс. Ага! Как раз такой случай и есть. Через год у него таблица вырастет в сто раз, а Вы будете советовать ради одной записи лопатить запрос по этой выросшей таблице? Агрегаты посоветуйте ещё. В общем, жизнь иногда далека от теории. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 15:11 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Симонов Денис, Вот об этом и речь. Получается простой запрос с группировкой очень неэффективно выполняется. Мне интересно, это именно ограничение Firebird, или тут проблема в самой постановке задачи. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 15:11 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C, расскажи, как же эффективно выполнять "простой запрос с группировкой" ? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 15:30 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Alexandr C, это смотря с какой стороны смотреть. Для группировки известны 2 способа: через сортировку (если можно прочесть в порядке индекса ORDER IDX) и HASH GROUP (это в Firebird не реализовано). Это хорошо работает для любой агрегатной функции. Когда нет группировки, то MIN и MAX при наличии индекса можно вычислить очень быстро. С другими агрегатами это не прокатит, придётся целиком сканировать таблицу. Придёт dimitr подскажет возможно ли что-то сделать в оптимизаторе ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 15:30 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Симонов ДенисДля группировки известны 2 способаЕсть ещё, но мне интересно что нам расскажет ТС ;) ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 15:35 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
hvladСимонов ДенисДля группировки известны 2 способаЕсть ещё, но мне интересно что нам расскажет ТС ;) Согласен с Вами, моими знаниями можно только повеселить знающих предмет обсуждения)) Поэтому и надеюсь на совет уважаемого сообщества ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 15:57 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
KreatorXXIу него таблица вырастет в сто раз, а Вы будете советовать ради одной записи лопатить запрос по этой выросшей таблице? Агрегаты посоветуйте ещё. и посоветую. Зачем заниматься онанизмом, постоянно перечитывая данные, которые увеличиваются с каждым годом? Ясен пень, что программист на начальном этапе разработки об этом не думает. Но думать-то надо. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 15:59 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Проблема "быстрой группировки" состоит только в получении всех client_id. Если есть отдельная таблица, где client_id уникальны - дальше всё просто. Для каждого client_id получить максимальное время уже не проблема. И хотя в плане пишется PLAN (TBL1 ORDER TBL_IDX1), на самом деле там ещё и INDEX TBL_IDX1, это не простой обход в порядке индекса. Кстати, max(tstamp) неправильно, поскольку рано или поздно получим 2 записи. Правильно писать first 1 tstamp ... order by tstamp desc ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 16:22 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
KreatorXXIЧерез год у него таблица вырастет в сто раз, а Вы будете советовать ради одной записи лопатить запрос по этой выросшей таблице? А через два года она вырастет в миллион раз и придёт время задуматься "а нужен ли мне этот запрос вообще". И таки да, тогда придёт время для хранимых агрегатов. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 16:36 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov, Не в таком простом случае. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 16:45 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
WildSeryПроблема "быстрой группировки" состоит только в получении всех client_id. Если есть отдельная таблица, где client_id уникальны - дальше всё просто. Для каждого client_id получить максимальное время уже не проблема. И хотя в плане пишется PLAN (TBL1 ORDER TBL_IDX1), на самом деле там ещё и INDEX TBL_IDX1, это не простой обход в порядке индекса. Кстати, max(tstamp) неправильно, поскольку рано или поздно получим 2 записи. Правильно писать first 1 tstamp ... order by tstamp desc Спасибо. Заменил на first 1 tstamp ... order by tstamp desc ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 16:48 |
|
Firebird 2.5 запрос MAX с группировкой
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov, В постановке задачи ТС агрегаты не потребуются. Видно, что max отрабатывается нормально. Например, каждый раз сумму считать - это да, согласен, наступит момент. Не надо из пушки по воробьям лупить. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.02.2018, 16:50 |
|
|
start [/forum/topic.php?all=1&fid=40&tid=1561245]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
47ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
69ms |
get tp. blocked users: |
1ms |
others: | 11ms |
total: | 166ms |
0 / 0 |