|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Привет всем. Заранее прошу прощения за многабукаф. Имеется некий программный источник, последовательно выдающий значения типа INTEGER (в принципе, аналог датасета). Серия данных составляет около 500000 значений, среди которых 50000 (около 10%) уникальных, т.е. в серии данных имеются повторяющиеся значения. Требуется из поступающей серии сохранить в БД уникальные значения. Что имеем: FB 2.5.4, Delphi, FIBPlus В тестовой БД реализована таблица для хранения значений: Код: plsql 1. 2. 3.
Все нижеописанные способы производились на одном и том же локальном компьютере, каждый вариант выполнялся по три раза, БД каждый раз пересоздавалась из скрипта. Каждая серия состояла из 500000 значений, среди которых 10% (50000) уникальных. 1. В БД реализована хранимая процедура для ввода значений: Код: plsql 1. 2. 3. 4. 5. 6.
В клиентской программе серия данных эмулировалась следующим кодом: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8.
Среднее время обработки серии составило примерно 320 секунд. После чего в теле хранимой процедуры был оставлен только EXIT, т.е. процедура вообще ничего не делала. Среднее время обработки серии составило примерно 140 секунд. Для 500000-кратного вызова пустой процедуры потребовалось 180 секунд. 2. С целью сокращения времени обработки серии было решено уменьшить количество вызовов хранимой процедуры посредством передачи в SP множества значений в виде строки с разделителем вида '12~1~4~123~'. Для парсинга передаваемой строки была реализована некая UDF, являющейся по сути однопроходным сканером переданной строки. Код: plsql 1. 2. 3. 4. 5.
Хранимая процедура был изменена: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
Код в клиентском приложении тоже изменился: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Среднее время обработки серии составило примерно 110 секунд (почти в 3 раза быстрее по сравнению с первым вариантом). 3. Было изменено объявление UDF: параметр CSTRING(32765) был объявлен, как CSTRING(16384), соответственно в хранимой процедуре параметр был изменен на VARCHAR(16384), в клиентской программе контроль максимальной длины был уменьшен до 16370. Среднее время обработки серии составило примерно 42 секунды. Собственно, вопрос: почему 3-й вариант быстрее 2-го в 2.5 раза, хотя варианты отличаются только объявлением максимально возможной длины строки (32765 во 2-м варианте и 16384 в 3-м). Неужели выделение памяти объемом 16K производится гораздо быстрее, нежели чем выделение памяти объемом 32K? С уважением, Polesov. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 01:24 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Извиняюсь, попутал После чего в теле хранимой процедуры был оставлен только EXIT, т.е. процедура вообще ничего не делала. Среднее время обработки серии составило примерно 140 секунд. Для 500000-кратного вызова пустой процедуры потребовалось 180 секунд. После чего в теле хранимой процедуры был оставлен только EXIT, т.е. процедура вообще ничего не делала. Среднее время обработки серии составило примерно 180 секунд, т.е. это время потребовалось для 500000-кратного вызова пустой процедуры. 140 секунд потребовалось для проверки 500000 и вставки 50000 значений. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 01:30 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Внешние таблицы не пробовал? ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 08:36 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Polesov, А если вместо варчара текстовый блоб? ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 09:25 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Polesov, Я бы сделал еще сделал insert во временную таблицу а потом insert into .. select .. from tmp group by ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 09:30 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Polesov3. Было изменено объявление UDF: параметр CSTRING(32765) был объявлен, как CSTRING(16384), соответственно в хранимой процедуре параметр был изменен на VARCHAR(16384), в клиентской программе контроль максимальной длины был уменьшен до 16370. Среднее время обработки серии составило примерно 42 секунды. Собственно, вопрос: почему 3-й вариант быстрее 2-го в 2.5 раза, хотя варианты отличаются только объявлением максимально возможной длины строки (32765 во 2-м варианте и 16384 в 3-м). Неужели выделение памяти объемом 16K производится гораздо быстрее, нежели чем выделение памяти объемом 32K?Очевидно - да. Попробуй строку в 28-30К, если интересно ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 09:43 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
hvlad, дело оказалось не в размере выделяемой памяти, а в длине передаваемой строки. Чуть позже выложу результаты. To All: вопрос не в том, как сделать быстрее, а почему такая разница по времени выполнения при различных длинах передаваемого параметра. С уважением, Polesov. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 11:32 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Шавлюк ЕвгенийЯ бы сделал еще сделал insert во временную таблицу А я бы сделал отсечение дубликатов ещё в приложении, без обращения к серверу вообще. Уверен, этот вариант выйграет по скорости со значительным отрывом. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 11:34 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
PolesovTo All: вопрос не в том, как сделать быстрее, а почему такая разница по времени выполнения при различных длинах передаваемого параметра. Из-за того, что у тебя stateless алгоритм в UDF и его сложность O(N^2/2). Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 11:47 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Dimitry SibiryakovPolesovTo All: вопрос не в том, как сделать быстрее, а почему такая разница по времени выполнения при различных длинах передаваемого параметра. Из-за того, что у тебя stateless алгоритм в UDF и его сложность O(N^2/2).С чего бы это ? Там POS передаётся в UDF ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 11:52 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
hvladС чего бы это ? Там POS передаётся в UDF Хммм... Действительно. Был неправ. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 12:20 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Dimitry SibiryakovИз-за того, что у тебя stateless алгоритм в UDF и его сложность O(N^2/2). Нет. Вот текст UDF: Код: pascal 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. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 12:48 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
PolesovНет. Действительно нет. Стало быть проблема действительно может быть в коде птицы. Возможно, она в избыточном преобразовании чарсетов при формировании параметра. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 12:55 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Шавлюк ЕвгенийЯ бы сделал еще сделал insert во временную таблицу а потом insert into .. select .. from tmp group by Аналогично. Но вместо временной таблицы использовал бы хранимку, для скорости. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 12:58 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Есть 3 места, где определяется максимально возможная длина строки: - объявление UDF - объявление входящего параметра SP - клиентское приложение, формирующее строку Провел несколько тестов. Каждый тест проводился 3 раза, перед каждым проведением БД пересоздавалась из скрипта. В UDF и SP длина параметра была объявлена 32765, только в клиентском приложении менялась максимально допустимая длина строки. Вот что получилось (другой компьютер, другая ОС, FB 2.5.4): Max len: 32750 - 28.9 сек Max len: 16370 - 24.6 сек Max len: 8180 - 21.4 сек Max len: 4080 - 20.2 сек Max len: 2040 - 20.0 сек Max len: 1020 - 20.0 сек Видно, что время обработки серии зависит от длины передаваемой строки (в случае с 32К и 2К почти в 1.5 раза). Any cojmments? С уважением, Polesov. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 13:03 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
fb user, в трёшке можно попробовать написать внешнюю хранимую процедуру для разделения значения. Думаю она могла бы работать гораздо быстрее. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 13:04 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
PolesovAny cojmments? непонятно, что тут комментировать. длиннее строка, медленнее выполнение. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 13:21 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Симонов Денис, У автора вопрос не с разбором строки. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 13:58 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
kdv, суммарная длина строк одинакова во всех случаях. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 14:01 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Симонов Денисв трёшке можно попробовать написать внешнюю хранимую процедуру для разделения значения. Думаю она могла бы работать гораздо быстрее. В своё время была идея написать сплит и для 2.5 через несколько функций handle = split_begin(blob, delimiter); value = split_get_next(handle); split_free(handle); Такой подход череват, но не всегда есть возможность внешнюю таблицу генерить для скорости. Я вот не плюсист, и жду когда умеющие напишут split для 3.0. Хотя есть мнение, что было бы неплохо сделать стандартной, для оптимизации по передаваемым типам данных и синтаксису. Но и внешняя вполне сгодилась бы. Вот у меня в базе приходится часто резать данные. Можно из вне толкать нарезку колбасы, но тогда получается дофига вставок, что опять выходит боком. Тему "а вот в слонике сделано..." тут не любят, но недавние тесты показали, что split там получается реально быстрым. FB-PSQL и MSSQL (2 реализации XML и CLR-процедура, с чистым substring на T-SQL совсем плохо) на порядок медленнее (буквально). И что радует, что PSQL в прице, даже не смотря на умеренно порождение временных блобов (сначала пилим блоб на varchar(32000), а потом пилим строки) дал результат сравнимый по скорости с CLR в MSSQL Что по-своему радует ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 14:25 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
Dimitry SibiryakovСтало быть проблема действительно может быть в коде птицы. Возможно, она в избыточном преобразовании чарсетов при формировании параметра. Вот это вполне может быть. Провел несколько тестов для различных CHARACTER SET при длине параметра 32К. Строка объявления параметра SP: Код: plsql 1.
Character set NONE - 48.4 сек Character set ASCII - 64.2 сек Character set WIN1251 - 28.4 сек Остается открытым вопрос, почему при одинаковых CHARACTER SET при 32К и 4К время обработки отличается почти в 1.5 раза. С уважением, Polseov. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 15:01 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
PolesovВидно, что время обработки серии зависит от длины передаваемой строки я комментирую то, что вы пишете. Не вижу вопроса в скорости в зависимости от длины строки. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 15:01 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
kdv, во всех случаях одинаковый суммарный объем передается кусками разной длины. От размера передаваемого куска зависит суммарное время обработки всего объема. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 15:05 |
|
Длинные варчары как парметры
|
|||
---|---|---|---|
#18+
afgm, я давно хотел попробовать написать UDR preg_split, но времени не хватает. 3.0 мы пока не используем в разработке, только тестируем на совместимость и прицениваемся к новым фичам. Как выйдет RC уже будем полномасштабно готовится к переезду. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2015, 15:14 |
|
|
start [/forum/topic.php?fid=40&msg=39066867&tid=1562606]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
41ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
54ms |
get tp. blocked users: |
1ms |
others: | 16ms |
total: | 154ms |
0 / 0 |