:: Игры Разума
Re: Игры разума 2
Prudivus

Сообщений: 4283
Откуда: Кишинев
Дата регистрации: 14.12.2006
Ага. А вариант с replace делает миллион записей за 2 сек.
Ratings: 0 negative/0 positive
Re: Игры разума 2
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
Э-э-э, а ф-ия 100 тыс сделала за 0.41 сек


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Игры разума 2
leonid
Автор

Сообщений: 3204
Откуда: Рига
Дата регистрации: 03.02.2006
AleksM
Зачудительно. 1,7сек. Тока _VFP.DoCmd
Черт, а на шестерке и с _VFP.DoCmd не работает, только ошибка уже другая. Кстати, объявления переменных, пожалуй тоже можно в _VFP.DoCmd засунуть, так что чистое решение получится. Но в моем первоначальном решении никакие переменные не использовались - чистый SQL, и работало около пол-секунды. Если до вечера никто не догадается, завтра утром выложу.
Ratings: 0 negative/0 positive
Re: Игры разума 2
AleksM

Сообщений: 17881
Дата регистрации: 11.11.2003
На лимоне скорость падает на порядок, 18,042сек.


------------------
Лучше переесть, чем недоспать.
Не спеши, а то успеешь.
Ratings: 0 negative/0 positive
Re: Игры разума 2
Prudivus

Сообщений: 4283
Откуда: Кишинев
Дата регистрации: 14.12.2006
Для интереса проделал это самое на MSSQL2K (MSDE):

create table #tmp (id int, f1 int, summ int)
declare @i int
set @i=1
while @i <= 100000
begin
INSERT INTO #tmp VALUES (@i, (RAND()*10+1), 0)
set @i = @i + 1
end
declare @s2 int
set @s2 = 0
update #tmp set @s2 = @s2+f1, summ = @s2
select * from #tmp
--drop table #tmp

Заполнение таблицы в цикле (100000 записей) - 50 сек.
Расчет набегающей суммы, первый раз - 37 сек.
Расчет набегающей суммы, повторно - 2 сек.

Тормоз, однако, MSSQL...
Ratings: 0 negative/0 positive
Re: Игры разума 2
Prudivus

Сообщений: 4283
Откуда: Кишинев
Дата регистрации: 14.12.2006
Да, есть вариант:
UPDATE tmp SET sum = NVL(t2.sum, 0) + tmp.f1 from tmp left join tmp t2 on tmp.id-1 = t2.id
Миллион делает за 12 сек.

А REPLACE - за 2.

К тому же, если будет пропуск в последовательности id - то все летит к чертям. В варианте с REPLACE такого не будет, все по-честному, корректно.



Исправлено 3 раз(а). Последнее : Prudivus, 15.03.07 19:39
Ratings: 0 negative/0 positive
Re: Игры разума 2
leonid
Автор

Сообщений: 3204
Откуда: Рига
Дата регистрации: 03.02.2006
Браво!
Для сравнения приведу авторский
UPDATE tmp SET sum=tmp.f1+NVL(t.sum,0) FROM tmp LEFT JOIN tmp t ON tmp.id=t.id+1

Цитата:
К тому же, если будет пропуск в последовательности id - то все летит к чертям. В варианте с REPLACE такого не будет, все по-честному, корректно.
Да я ничего и не говорю, конечно, такие задачи надо решать с помощью replace. Просто хотелось продемонстрировать некоторые возможности SQL.

P.S.
А еще у меня возникли сомнения по поводу выполнения на MS SQL
declare @s2 int
set @s2 = 0
update tmp set @s2 = @s2+f1, sum = @s2
А где гарантия, что update будет выполняться в правильном порядке? Насколько я помню, MS SQL это не гарантирует?
Ratings: 0 negative/0 positive
Re: Игры разума 2
AleksM

Сообщений: 17881
Дата регистрации: 11.11.2003
Цитата:
Для сравнения приведу авторский
UPDATE tmp SET sum=tmp.f1+NVL(t.sum,0) FROM tmp LEFT JOIN tmp t ON tmp.id=t.id+1
Крутился рядышком вокруг этого, НО не докрутился.


------------------
Лучше переесть, чем недоспать.
Не спеши, а то успеешь.
Ratings: 0 negative/0 positive
Re: Игры разума 2
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
leonid
Для сравнения приведу авторский

Мда-с, не ожидал, что при опубликовании решения появится дополнительное условие

leonid
А еще у меня возникли сомнения по поводу выполнения на MS SQL
declare @s2 int
set @s2 = 0
update tmp set @s2 = @s2+f1, sum = @s2
А где гарантия, что update будет выполняться в правильном порядке? Насколько я помню, MS SQL это не гарантирует?

Есть один способ - это использование кластерного индекса

create table #t (f1 int primary key clustered, sum int)
insert into #t (f1, sum) values (2,0)
insert into #t (f1, sum) values (1,0)
insert into #t (f1, sum) values (3,0)
declare @s2 int
set @s2 = 0
update #t set @s2 = @s2+f1, sum = @s2
select * from #t
drop table #t


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Игры разума 2
Prudivus

Сообщений: 4283
Откуда: Кишинев
Дата регистрации: 14.12.2006
declare @s2 int
set @s2 = 0
update #t set @s2 = @s2+f1, sum = @s2
Кластеризация необязательна, если речь идет о временных таблицах (или переменных-таблицах), проверено на работающей задаче. Хотя, конечно, штука не очень корректная/документированная... Порядок явно не задан, присвоение переменной в update тоже вещь сомнительная, переносимость на другие платформы не гарантирована. Но работает быстрее всех прочих вариантов.
Ratings: 0 negative/0 positive
Re: Игры разума 2
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
Prudivus
declare @s2 int
set @s2 = 0
update #t set @s2 = @s2+f1, sum = @s2
Кластеризация необязательна, если речь идет о временных таблицах (или переменных-таблицах), проверено на работающей задаче. Хотя, конечно, штука не очень корректная/документированная... Порядок явно не задан, присвоение переменной в update тоже вещь сомнительная, переносимость на другие платформы не гарантирована. Но работает быстрее всех прочих вариантов.

Ну не скажи, давай приведем условие к исходной задаче

create table #t (id int primary key clustered , f1 int , sum int)
insert into #t (id, f1, sum) values (3, 3,0)
insert into #t (id, f1, sum) values (2, 1,0)
insert into #t (id, f1, sum) values (1, 5,0)
declare @s2 int
set @s2 = 0
update #t set @s2 = @s2+f1, sum = @s2
select * from #t
drop table #t
create table #tt (id int , f1 int , sum int)
insert into #tt (id, f1, sum) values (3, 3,0)
insert into #tt (id, f1, sum) values (2, 1,0)
insert into #tt(id, f1, sum) values (1, 5,0)
set @s2 = 0
update #tt set @s2 = @s2+f1, sum = @s2
select * from #tt
drop table #tt

Обрати внимание на суммы для кластерного id = 1 sum = 5, а для не кластерного id = 1 sum = 9

Цитата:
id f1 sum
----------- ----------- -----------
1 5 5
2 1 6
3 3 9

id f1 sum
----------- ----------- -----------
3 3 3
2 1 4
1 5 9


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Игры разума 2
leonid
Автор

Сообщений: 3204
Откуда: Рига
Дата регистрации: 03.02.2006
PaulWist
Мда-с, не ожидал, что при опубликовании решения появится дополнительное условие
А что за условие? Я что-то не заметил.
Ratings: 0 negative/0 positive
Re: Игры разума 2
Prudivus

Сообщений: 4283
Откуда: Кишинев
Дата регистрации: 14.12.2006
PaulWist
В базовом условии задачи было что записи отсортированы по возрастанию ПК, а в твоем примере - сортируются то так то эдак (по убыванию: 3, 2, 1). Поэтому и результат разный.
Ratings: 0 negative/0 positive
Re: Игры разума 2
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
leonid
PaulWist
Мда-с, не ожидал, что при опубликовании решения появится дополнительное условие
А что за условие? Я что-то не заметил.

Э-э-э, вот это

Цитата:
К тому же, если будет пропуск в последовательности id - то все летит к чертям.

Те тестовые данные конечно удовлетворяют первоначальной задаче, НО только для именно таких данных, что не является решением в общем случае.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Игры разума 2
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
Prudivus
PaulWist
В базовом условии задачи было что записи отсортированы по возрастанию ПК, а в твоем примере - сортируются то так то эдак (по убыванию: 3, 2, 1). Поэтому и результат разный.

В том-то и дело, что если заполнить 1,2,3 то это будет частный случай, исключение, для общего решения когда записи добавляются не в порядке возрастания спасет только кластерный индекс, который "своей волей" физически положит записи в нужном нам порядке.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Игры разума 2
leonid
Автор

Сообщений: 3204
Откуда: Рига
Дата регистрации: 03.02.2006
При формулировке задачи был приведен код формирования данных. Не понимаю, почему кем-то придуманные дополнительные условия можно считать появившимися при опубликовании авторского решения.
Ratings: 0 negative/0 positive
Re: Игры разума 2
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
leonid
При формулировке задачи был приведен код формирования данных. Не понимаю, почему кем-то придуманные дополнительные условия можно считать появившимися при опубликовании авторского решения.

Вопрос (обвинение ) снимается, только мне кажется, что решение должно быть общим и не зависить от данных. ;)


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Игры разума 2
leonid
Автор

Сообщений: 3204
Откуда: Рига
Дата регистрации: 03.02.2006
PaulWist
только мне кажется, что решение должно быть общим и не зависить от данных. ;)
В приведенной задаче данные - это поле f1. От них решение не зависит.
Ratings: 0 negative/0 positive
Re: Игры разума 2
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
leonid
PaulWist
только мне кажется, что решение должно быть общим и не зависить от данных. ;)
В приведенной задаче данные - это поле f1. От них решение не зависит.

Ну наверное не зависит.

Только не работает приведенный код

CREATE CURSOR tmp (id i, f1 i, sum i DEFAULT 0)
INSERT INTO tmp (id, f1) VALUES (2, 2)
INSERT INTO tmp (id, f1) VALUES (1, 1)
UPDATE tmp SET sum=tmp.f1+NVL(t.sum,0) FROM tmp LEFT JOIN tmp t ON tmp.id=t.id+1
BROWSE

А так работает

CREATE CURSOR tmp (id i, f1 i, sum i DEFAULT 0)
INSERT INTO tmp (id, f1) VALUES (1, 1)
INSERT INTO tmp (id, f1) VALUES (2, 2)
UPDATE tmp SET sum=tmp.f1+NVL(t.sum,0) FROM tmp LEFT JOIN tmp t ON tmp.id=t.id+1
BROWSE

Лично для меня такое решение является не правильным.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Игры разума 2
Prudivus

Сообщений: 4283
Откуда: Кишинев
Дата регистрации: 14.12.2006
Повторюсь:
Цитата:
Кластеризация необязательна, если речь идет о временных таблицах (или переменных-таблицах), проверено на работающей задаче.
Имеется в виду что при выборке реальных данных во временную таблицу (курсор в терминах фокса), всегда есть возможность явно задать сортировку. А без сортировки - да, конечно работать не будет, и единственно правильно использовать вложенные селекты. Но на больших объемах это катастрофическая потеря быстродействия, поэтому и приходится придумывать подобные методы. Это все из реальной практики. Похожую тему я поднимал в "Вопросы не для собеседования". Там предлагалось найти "академическое" решение связывания таблиц M-N, в котором как подзапрос вычисляется и набегающая сумма...



Исправлено 1 раз(а). Последнее : Prudivus, 16.03.07 11:52
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 4 (Гостей: 4)

© 2000-2024 Fox Club 
Яндекс.Метрика