|
|
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Господа! Хелп!! Третий день парюсь над SQL-запросом, ничего не получается, скорее всего туплю, и решение должно быть очевидным... Задача: выбрать из таблицы: ID товара (GOOD_ID) и его цену(PRICE_I), причем цена должна быть выбрана для самой последней дате изменения товара (EDIT_TIME). В таблице 200000 записей! Т.е. сложные запросы с подзапросами вешают сервак намертво :) Сама таблица: GOOD_ID, PRICE_I, EDIT_TIME, .... Для примера данные: Код: plaintext 1. 2. 3. 4. 5. 6. 7. Вариант с процедурами не подходит, нужен именно SQL-запрос. Подозреваю, что нужно юзать псевдонимы и RDB$DB_KEY??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 12:28 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
А кто мешает выполнить Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 12:47 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
SELECT T1.GOOD_ID, T1.PRICE_I FROM Table T1 WHERE T1.EDIT_TIME= (SELECT MAX(T2.EDIT_TIME) FROM Table T2 WHERE T2.GOOD_ID=T1.GOOD_ID) ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 12:49 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
А индекс на EDIT_TIME есть? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 13:00 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Ну так-то оно так, но сколько будет выполнять ся этот запрос? Можно прикинуть 200000 * 200000 ? Или я ошибаюсь ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 13:05 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>Dnico 200000*200000 - это количество минут или секунд ? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 13:11 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>200000*200000 - это количество минут или секунд ? Это видимо двести тысяч РАЗ по двести тыщ запросов. Секунды зависят от железки;-) И, осмелюсь предположить, _от индексов_. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 13:20 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
> 200000*200000 - это количество минут или секунд ? Количество проходов причём натурал! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 13:21 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>Moses Если запросов, то я вижу 1*200000 И, конечно, индексирование влияет... (на скорость)... :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 13:23 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Johnmen А самому проверить ? Я вот ради интереса проверил ... у меня зашкалило за 24 мульена ... а зписей 17000. Ну так как? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 13:32 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>Dnico Что проверить ? Количество выполненных запросов ? Количество времени ? Другое ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 13:38 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Johnmen Кол-во запросов! А время зависит от индексов. Это как раз самое простое - добавил индекс и гуляй себе ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 13:40 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>Dnico Количество запросов = 1*200000. А что такое у тебя "24 мульена " ? И где это видно ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 13:48 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Зделал, как посоветовал Johnmen: SELECT T1.GOOD_ID, T1.PRICE_I FROM PRICES T1 WHERE T1.EDIT_TIME= (SELECT MAX(T2.EDIT_TIME) FROM PRICES T2 WHERE T2.GOOD_ID=T1.GOOD_ID) И пошёл курить: ------ Performance info ------ Prepare time = 0ms Execute time = 6m 27s 953ms Avg fetch time = 15 518,12 ms Current memory = 11 717 858 Max memory = 12 439 626 Memory buffers = 2 048 Reads from disk to cache = 9 410 Writes from cache to disk = 6 Fetches from cache = 6 716 061 P.S. Индекса на EDIT_TIME нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 13:51 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Johnmen Откуда взяться 1*200000 ? Для каждой записи из T1 используется проход по всем записям в T2. Умножаем ... получаем !!! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 13:52 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>Nikita Krivtsov Если идет борьба за производительность, то делай, как уже советовал Dnico, ХП. Тогда достаточно будет одного запроса с соотвествующим ORDER BY и прописанной логикой "отброса" ненужных записей в ХП. >Dnico >Откуда взяться 1*200000 ? Основной запрос - 1, для каждой записи основного (200000)- вложенный запрос. Итого 1*200000 запросов. >Для каждой записи из T1 используется проход по всем записям в T2. Ну да, кто спорит ? >Умножаем ... получаем !!! Так что же получаем ? Чего и в каких единицах ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 14:02 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Лучше всего всеже использовать процедуру: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 14:08 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Вчера делал такой запрос: Код: plaintext 1. 2. 3. 4. 5. (where pricelist_id=2 ) -идентификатор прайс-листа, впринципе не столь важен для нашего запроса Он не совсем правильный, но может быть от него отталкиваться??? По крайней мере выполнялся несколько секунд. P.S. Да забыл указать, что после выборки из таблицы где 200000 записей, в результате должно получиться 10000 записей. И еще такая проблема: изменять базу я не могу, т.е. не могу индексы добавить, не могу процедуры и т.д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 14:08 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>Dnico Это те же 200000 запросов... >Nikita Krivtsov Максимально быстро, в один запрос (ХП) : Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Обращение к ХП - как обычно, SELECT * FROM MyProc ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 15:14 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Может быть так: select GOOD_ID, EDIT_TIME, max(PRICE_I) from TABLE order by GOOD_ID having EDIT_TIME = (select max(EDIT_TIME) from TABLE) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 16:31 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>Vagoo Не может быть так...:) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 16:59 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Осмелюсь предположить что записи в таблице просто не разграничены периодами предположим по месячно, предлагаю завести поле которое будет обозначать период и ес-но индекс по этому полю, а далее я думаю ни какой вложеный запрос не положит сервак, так как будет выбираться не все ко-во записей а только по текущему периоду, однако надо бы устаканить случай когда запись по данному критерю последний раз появлялась в предыдущих периодах , однако это очень просто реализовать в процедуре. У нас так все прекрасно работает проблем нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2003, 17:50 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
2 Johnmen > Основной запрос - 1, для каждой записи основного (200000)- вложенный > запрос. Итого 1*200000 запросов. Для основного прохода считывается 200000 записей и для каждой записи опять же считывается 200000 записей! Отсюда и 200000*200000! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 04:15 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Народ, начнем с того что давайте заведем индексы по дате... это первое... далее декартово произведение кол-ва записей это при джойнах... в данном случае будет просто сумма. подобный запрос который предлагали у меня работает менее секунды, при индексах разумеется. А Having вообще враги придумали, по крайней мереэто более чем не подходит для данного случая, потому как последний вообще не ходит по индексам и отрабатывает он после получение результатов от секции Where после группировки и подсчета агрегатных функций. ТОбишь когда про индексы и вспоминать как-то поздно... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 04:58 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>Fighter Чего 200000*200000 ??? Убитых енотов ? Буказоидов ? Другое ? Вообще непонятно, о чем спор... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 09:31 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Johnmen Извиняй за грубость, но для непонятливых : Не Убитых енотов, не Буказоидов и уж точно не Другое, а просто IB(FB) читает записи и количество этих чтений 200000*200000 = 40 000 000 000 (записей). Такой запрос будет неделю выполняться ... P.S. И эту проблему не решить иначе, чем использовать ХП, а поскольку у Nikita Krivtsov нет возможности вносить изменения (хотя почему такие жесткие условия), то решения просто нет ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 10:06 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
StarWind подобный запрос который предлагали у меня работает менее секунды, при индексах разумеется. Не забывай про кол-во записей в таблице, у меня тоже "быстро" (30 сек) , но их там 17000. А тут и индексов нет ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 10:13 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Dnico Сорри, я забыл указать кол-во записей в таблицах... порядка 300000 пропишу прописью, триста тысяч! и не надо заливать что ХП единственная возможность ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 10:20 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
StarWind НЕ ВЕРЮ - ПИШИ ЗАПРОС ПРОВЕРЮ НА СВОИХ 300000 записях ... Индекс по дате есть ... и по ID тоже ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 10:38 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>Dnico >Извиняй за грубость, но для непонятливых : Да все нормально. И я к ним не отношусь. А по поводу чтений - неужели ты думаешь, что за 1 (одну) операцию чтения читается одна запись ??? :) Поверь, это совсем не так. Единицой чтения является страница. На которой м.б. несколько записей. Поэтому указанное тобой произведение 200000*200000 ни о чем не говорит. И уж тем более неделя здесь совсем неуместна...:) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 10:44 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Johnmen Если вдаваться в подробности, то я согласен, там все не так просто, но все равно существует элементарные операции выборки записей. Так вот я говорю об этом количестве выборок ... И существует еще и реальный пример, который показывает статистику выполнения запроса. Могу показать ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 10:52 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
select * from table1 where dtime = (select max(dtime) from table1) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 10:57 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
StarWind Ну и что дает этот запрос ? Ничего того, что нужно ... Тем более одну запись ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 11:03 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>StarWind Ни-ни...:) >Dnico Да нет, не надо... Уже отклонились от темы. А по ней видится 2 решения, каждое из которых надо попробовать : 1. Индекс+Запрос 2. ХП с соотв-ей логикой И п.2, скорее всего, в данном случае, самое быстрое решение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 11:04 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
сорри, протупил с запросом.... но честно гвооря надо проэксперементировать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 11:06 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Johnmen Вот я и говорю, что через запрос это просто почти невозможно ... очень долго. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 11:10 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
************************************************************** select good_id, price, last_edt from table_2000 t1 where last_edt=(select max(last_edt) from table_2000 t2 where t2.good_id = t1.good_id) ------ Performance info ------ Prepare time = 3ms Execute time = 16s 516ms Avg fetch time = 4 129,00 ms Current memory = 18 118 656 Max memory = 18 398 384 Memory buffers = 2 048 Reads from disk to cache = 0 Writes from cache to disk = 6 Fetches from cache = 8 033 956 ************************************************************** select t1.good_id, price, max(t1.last_edt) from table_2000 t1 group by good_id, price having last_edt=(select max(t2.last_edt) from table_2000 t2 where t2.good_id = t1.good_id) ------ Performance info ------ Prepare time = 4ms Execute time = 16s 188ms Avg fetch time = 952,24 ms Current memory = 18 124 800 Max memory = 18 398 384 Memory buffers = 2 048 Reads from disk to cache = 0 Writes from cache to disk = 0 Fetches from cache = 7 840 702 ************************************************************** select good_id, max(last_edt), (select max(price) from table_2000 t2 where t2.table_id = t1.table_id) as price from table_2000 t1 group by good_id ------ Performance info ------ Prepare time = 6ms Execute time = 127ms Avg fetch time = 7,47 ms Current memory = 18 263 128 Max memory = 18 518 296 Memory buffers = 2 048 Reads from disk to cache = 0 Writes from cache to disk = 6 Fetches from cache = 14 057 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 12:28 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>Vagoo В последнем примере ошибка :) И даже не одна... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 15:48 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
> Johnmen Может быть. Зато оно работает и дает правильный результат :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 16:06 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Vagoo Execute time = 127ms Отличный результат, только вот один вопрос: По каким полям у тебя индексы и какой план получается? P.S. И ище у тебя комп случаем не 64-х процессорный ? А то я уже минут пять жду результатов по этому запросу? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 16:24 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>Vagoo И результат дает неверный :) Неверный принципиально ! Верный результат - это тебе так кажется, поскольку он основан на твоих данных, которые обладают специфической однобокостью. (Напр. макс. дате соответствует макс.цена, что не явл-ся обязятельным) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 16:24 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
Вот мои результаты : Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 16:47 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
> Dnico select id, max(dt), (select max(price) from delivery t2 where t2.id = t1.id) as price from delivery t1 group by id В твоем запросе существует один ID , который по всей видимости товар. А у меня GOOD_ID - товар, TABLE_ID - идентификатор записи, он же праймери кей, естественно он же и индекс. Поэтому и время отличается, наверное. > Johnmen Что касается однобокости - то действительно я таблицу сгенерил. Но после этого внес руками изменения в несколько рекордов, для контроля. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 17:11 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
>Dnico Вот это абсолютно похоже на правду ! Единственное не max(price), а max(date). >Vagoo Еще раз попытаюсь объяснить, что твой запрос ПРИНЦИПИАЛЬНО НЕВЕРЕН ! Потому, что соединять надо не по ключу, а по идентификатору товара ! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 17:53 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
> Johnmen Я не отрицаю, что запрос принципиально не верен. Я его сделал случайно и очень удивился когда оно заработало. Более того, специально слепил таблицу на 200000 строк и убедился что цена получается неправильная, хоть и работает бысто :( Но почему тогда запрос из таблицы в 2000 строк дает верный результат ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2003, 18:51 |
|
||
|
Выборка данных без дубликатов из таблицы в 200000 записей
|
|||
|---|---|---|---|
|
#18+
И все равно получается ерунда ... не дает все это нужного результата ... УВЫ! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2003, 10:17 |
|
||
|
|

start [/forum/topic.php?all=1&fid=40&tid=1580085]: |
0ms |
get settings: |
9ms |
get forum list: |
19ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
77ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
86ms |
get tp. blocked users: |
2ms |
| others: | 244ms |
| total: | 456ms |

| 0 / 0 |
